繁体   English   中英

结合通用方法和重载

[英]Combining generic methods and overloads

我有以下方法:

public void Set<T>(IEnumerable<T> records)
{
     foreach (var record in records)
     {
        Set(record);
     }
 }

我希望调用以下任一Set方法,具体取决于T

    public void Set(RecordType1 record)
    {
        // Some RecordType1 logic
    }

    public void Set(RecordType2 record)
    {
        // Some logic applicable to RecordType2 only
    }

希望您可以看到我正在尝试允许在运行时调用哪个Set方法。 这“不起作用”(即不会编译,因为它期望RecordType1 )。

在将记录发送到Set方法之前,如何在不测试类型的情况下保留这种结构?

为什么不创建接口( IRecordType ),允许RecordType1RecordType2继承它,然后将每个Set方法的主逻辑移动到接口。

public interface IRecordType
{
    void Set(...);
}
public void Set(IEnumerable<IRecordType> records)
{
    foreach (var record in records)
    {
        record.Set(...);
    }
}

这是一种更易于维护的解决方案。 它还允许更好的多态性。

编辑:要查看的资源: https//msdn.microsoft.com/en-us/library/3b5b8ezk%28v=vs.90%29.aspx

此外,小侧边栏:使用interface您不仅可以共享某些方法,还可以共享属性和事件。 如果RecordType1RecordType2共享几个公共属性,则可以将这些属性添加到interface ,然后在以前需要的任何地方使用IRecordType来区分这两个属性,方法或事件。 同样地,内部的任何的那些属性,方法和事件代码允许依靠其他属性,方法,事件或特定于对象本身的字段。 这是面向对象语言( C# )和多态的目的。

编辑:作为评论中讨论的结果,我还想添加有关使用OOP方法( interfaceabstract classclass )和StriplingWarrior建议的dynamic方法之间决策的更多信息:

如果您无法访问RecordType1RecordType2的实际实现细节,或者您无法更改应用程序的设计(由于阻碍了对Set(RecordType1)Set(RecordType2)方法的依赖,您可能会发现采用dynamic方法更有成效。还有其他选择,我们可能没有想到 - 你总是可以给它们一个去。 dynamic方法的缺点是它需要.NET 4.0。

此外,还有更多注意事项:如果您确实可以访问RecordType1RecordType2实现细节,但是无法更改Set(RecordType1)Set(RecordType2) ,只要定义,您可以随时修改它们的主体:

public void Set(RecordType1 record)
{
    record.Set(...);
}

public void Set(RecordType2 record)
{
    record.Set(...);
}

这样可以保留整个应用程序结构,同时还可以减少代码维护并允许多态性。

如果你是积极的,给定的集合中的每个项目将匹配方法签名,你可以投的值作为dynamic ,让运行弄清楚如何将其绑定到:

 foreach (var record in records)
 {
    Set((dynamic)record);
 }

但是,这很容易出错 ,我建议你仔细看看你真正要完成的事情。 最有可能是一种更好的模式来满足您的需求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM