首页 > 解决方案 > 返回派生泛型类而不指定返回类型的方法

问题描述

我有一个这样的基类:

public class BaseClass<T, R> : DbContext where T : class, IAPIObject<R>
{
    public void MethodA()
    {
        Something using T
        Something using R
    }
}

我有一些这样的派生类:

public class DerivedClass1 : BaseClass<TypeA, TypeB>
public class DerivedClass2 : BaseClass<TypeC, TypeD>

我想编写如下函数,但不指定返回对象的类型,因为它们是在派生类中定义的:

private BaseClass GetObject<T>(T apiObject)
{
    return apiObject switch
        {
            TypeA _ => DerivedClass1(),
            TypeC _ => DerivedClass2(),
        }
}

这可能吗?这是一个好主意吗?我觉得这有可能是设计这个东西的完全错误的方式,但我不是太有经验。

最终目标是能够获得具有基于某些参数定义的类型的 BaseClass 实例,然后执行 BaseClass.MethodA() 之类的操作,而不再担心指定类型:

var thing = GetObject<TypeA>(someObject);
thing.MethodA();

如果我在方法本身上定义类型,那么我每次调用 MethodA() 时都必须定义它们,如果我知道 DerivedClass1 将始终使用 TypeA 和 TypeB,这感觉是多余的。有没有更好的方法来使用虚拟方法和覆盖来做到这一点?

标签: c#genericsinheritancederived-class

解决方案


由于您尝试调用的方法的签名 ( MethodA) 不涉及类型参数(只有其实现使用类型参数),您可以创建一个非泛型接口:

interface IBaseClass {
    void MethodA();
}

// change the return type to the non-generic interface
private IBaseClass GetObject<T>(T apiObject) =>
    apiObject switch
    {
        TypeA _ => DerivedClass1(),
        TypeC _ => DerivedClass2(),
        // you seem to be missing a default case?
    };

在这个非通用接口IBaseClass上,您可以调用MethodA

由于您对返回的对象一无所知TR因此您不能使用BaseClass涉及这些类型的任何成员。IBaseClass您是否向编译器承诺“我不会使用任何涉及Tand的成员R”。


推荐阅读