动态转换调用适当的重载

时间:2013-01-08 18:39:54

标签: c# generics

我有一个公共泛型方法,它接受一个通用参数。我还有一些私有方法接受我从泛型方法调用的具体类型参数。为了更好地描述我的问题,请看下面的代码:

    public void Save<T>(T entity) where T : class
    {
        if(entity is LibraryItem)      Save(entity as LibraryItem);
        else if(entity is Folder)      Save(entity as Folder);
        else if(entity is ProductType) Save(entity as ProductType);
        else if(entity is ProcessName) Save(entity as ProcessName);
    }

私人方法:

private void Save(ProcessName proc){}
private void Save(ProductType type){}
private void Save(Folder folder){}
...

查看代码,我真的不喜欢这个解决方案,检查每个可能的类型看起来像是一个不好的做法imho。所以我想知道我的问题是否有更清洁的解决方案?也许可以在运行时动态转换T并调用适当的私有方法?

3 个答案:

答案 0 :(得分:6)

使用运行时类型定义:

public void Save<T>(T entity) where T : class
{
    Save((dynamic)entity);
}

private void Save(LibraryItem lib){}
private void Save(ProcessName proc){}
private void Save(ProductType type){}
private void Save(Folder folder){}

您还需要一个带有对象类型参数的方法来处理实体不是LibraryItem,ProcessName,ProductType或Folder的情况:

private void Save(object obj) {  }

答案 1 :(得分:3)

你走在正确的轨道上。使用dynamic关键字获取运行时overload resolution

Save((dynamic)entity);

通常在编译期间对静态类型(对于泛型类型object)执行重载解析。通过强制转换为dynamic,您可以将分辨率推迟到运行时间,并使用运行时类型而不是静态类型。

答案 2 :(得分:1)

理想的机制是采用Save特定于该类型的任何方面,并使其成为每种具体类型的一部分,以便您可以使用多态性。

每个项目可能不适合自行保存,但它应该做的是暴露足够的信息以允许其他人编写一个简单接受接口或基类型的通用Save方法其中所有类型都实现了为类型公开足够的信息以允许它被保存。