【问题标题】:Invoke generic method on all the derived types in type hierarchy对类型层次结构中的所有派生类型调用泛型方法
【发布时间】:2019-08-07 09:10:26
【问题描述】:

假设我们有以下类型层次结构:

public abstract class Base {}
public class A : Base {}
public class B : Base {}

我需要对来自Base 的所有派生类型执行相同的操作。这是我想出来的

public IList<T> DoWork<T>(string entityPath) where T : Base {
    // get 'json' using 'entityPath'
    return JsonConvert.DeserializeObject<List<T>>(json);
}

现在我的问题是以某种方式在消费者类的 for 循环中对所有派生类调用 DoWork()。我希望工作是这样的:

var entities = new Dictionary<string, Type> {
    ['a', TypeOf(A)],
    ['b', TypeOf(B)]
}
foreach(var e in entitties) {
    DoWork<e.Value>(e.Key)
}

这显然是行不通的。

如果这种方法完全有缺陷,我很想知道替代方案。

【问题讨论】:

    标签: c#


    【解决方案1】:

    如果您在编译时不知道类型,则不能使用泛型,但幸运的是,JsonConvert.DeserialiseObject 有一个重载,它接受一个字符串和一个 Type

    因此,您可以添加非泛型的 DoWork 重载:

    public object DoWork(string entityPath, Type type) {
        // get 'json' using 'entityPath'
        var listType = typeof(List<>).MakeGenericType(type);
        return JsonConvert.DeserializeObject(json, listType);
    }
    

    然后像这样在 for 循环中调用它:

    foreach(var e in entitties) {
        DoWork(e.Key, e.Value); // why are you ignoring the return value?
    }
    

    【讨论】:

    • 在实际代码中,没有忽略返回值。第一句是否意味着即使是基本类型也不能以多态方式使用(即DoWork&lt;Base&gt;(path),其中Base实际上是A的一个实例)?
    • 在声明DoWork&lt;Base&gt;(path) 中,Base 就是Base。不能是ABase 是一个类型,而 type 不能是另一个 type 的实例,所以我不太清楚你的意思是什么...... @havij
    • 哦,nvm 那是一个愚蠢的问题,我需要学习更多关于泛型的知识,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-09-14
    • 2013-03-20
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    相关资源
    最近更新 更多