C#Generic Class,如何使用类型参数的派生类的公共属性?

时间:2016-07-05 07:49:40

标签: c# visual-studio generics constraints

我在C#中有两个类:

public abstract class BaseAccount
{
    public void MyMethod1()
    {
        //Code
    }
}

public class DerivedAccount : BaseAccount
{
    public  void MyMethod2()
    {
        //code
    }
}

public class AccountBL<T> where T : BaseAccount, new()
{
    public void TestMethod()
    {
        T obj1 = new T();
        obj1.MyMethod1();
        obj1.MyMethod2(); //Wrong!!! Can I use a method in derived class without changing constaint??
    }       
}    

如何在泛型类中使用派生类的公共属性

我不希望为每个Derived Class实现几个泛型类。

4 个答案:

答案 0 :(得分:3)

定义包含您要访问的成员的接口,然后将type参数限制为实现该接口的类型。

public IMyInterface {
  void MyMethod2();
}

public class AccountBL<T> where T : BaseAccounbt, new(), IMyInterface {
  // Members can access T.MyMethod2()
}

与其他一些语言不同,C#只允许引用符合类型参数要求的类型参数的成员。

答案 1 :(得分:2)

如果您想使用DerivedAccount.Method2(),则此愿望已经 约束。您显然需要T成为DerivedAccount。

可以做类似的事情:

 (obj1 as DerivedAccount)?.MyMethod2();

但我个人不喜欢混合类型演员和仿制品。如果您的方法是通用的,则意味着您不关心特定的运行时类型(除了它应该是BaseAccount)。然后添加类型检查似乎有点奇怪。

答案 2 :(得分:1)

这是因为你的结构。使用where T : BaseAccount, new()表示T必须从BaseAccount继承,因此您可以使用BaseAccount中的方法。如果您想使用DerivedAccount中的方法,您必须先检查一下:

if (obj1 is DerivedAccount ) {}

然后将其投射为DerivedAccount。所以你得到以下内容:

public class AccountBL<T> where T : BaseAccount, new()
{
    public void TestMethod()
    {
        T obj1 = new T();
        obj1.MyMethod1();

        if (obj1 is DerivedAccount )
        {
             (obj1 as DerivedAccount).MyMethod2();
        }
    }       
} 

这里有一个可执行的示例:https://dotnetfiddle.net/NwxPRt

答案 3 :(得分:0)

这是因为你的结构。在T : BaseAccount, new()处,您必须从BaseAccount继承T,因此您可以使用BaseAccount中的方法。如果您想使用DerivedAccount中的方法,您必须先检查一下。