3 c# generics methods types overloading
我有以下方法:
public void Set<T>(IEnumerable<T> records)
{
foreach (var record in records)
{
Set(record);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望Set
调用以下任一方法之一,具体取决于T
:
public void Set(RecordType1 record)
{
// Some RecordType1 logic
}
public void Set(RecordType2 record)
{
// Some logic applicable to RecordType2 only
}
Run Code Online (Sandbox Code Playgroud)
希望您可以看到我正在尝试允许Set
在运行时推断调用哪个方法.这"不起作用"(即不会像预期的那样进行编译RecordType1
).
题
在将记录发送到Set
方法之前,如何在不测试类型的情况下保留此类结构?
410*_*one 13
为什么不创建一个接口(IRecordType
),允许RecordType1
并RecordType2
继承它,然后将每个Set
方法的主要逻辑移动到接口.
public interface IRecordType
{
void Set(...);
}
public void Set(IEnumerable<IRecordType> records)
{
foreach (var record in records)
{
record.Set(...);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一种更易于维护的解决方案.它还允许更好的多态性.
编辑:要查看的资源:https://msdn.microsoft.com/en-us/library/3b5b8ezk%28v=vs.90%29.aspx
此外,小侧边栏:使用interface
s,您不仅可以共享某些方法,还可以共享属性和事件.如果RecordType1
并RecordType2
共享几个常见属性,则可以将这些属性添加到该属性中interface
,然后IRecordType
在以前需要的任何位置使用,以区分这两个属性,方法或事件.同样地,内部的任何的那些属性,方法和事件代码被允许依靠其他属性,方法,事件或特定于对象本身的字段.这是面向对象语言(C#)和多态的目的.
编辑:正如在评论中讨论的结果,我也想补充有关使用OOP的方法(之间的决策更多信息interface
,abstract class
,class
)和dynamic
StriplingWarrior建议的方法:
如果你没有获得实际的实施细则RecordType1
或者RecordType2
,或者你无法改变你的应用程序的设计(由于在该阻挡的依赖Set(RecordType1)
和Set(RecordType2)
方法,你会发现它更富有成效的把他的使用方法dynamic
.还有其他选择,我们可能没有想到 - 你总是可以给他们一个去.这种dynamic
方法的缺点是它需要.NET 4.0.
此外,还有更多注意事项:如果您确实有权访问RecordType1
和RecordType2
实现详细信息,但无法更改Set(RecordType1)
,Set(RecordType2)
并且就定义而言,您可以随时修改它们的主体:
public void Set(RecordType1 record)
{
record.Set(...);
}
public void Set(RecordType2 record)
{
record.Set(...);
}
Run Code Online (Sandbox Code Playgroud)
这样可以保留整个应用程序结构,同时还可以减少代码维护并允许多态性.
如果你肯定给定集合中的每个项都与方法签名匹配,你可以将值转换为,dynamic
并让运行时找出将它绑定到的内容:
foreach (var record in records)
{
Set((dynamic)record);
}
Run Code Online (Sandbox Code Playgroud)
但是,这很容易出错,我建议你仔细看看你真正要完成的事情.最有可能是一种更好的模式来满足您的需求.