指定泛型类,其中T应该是其他类型的子类

时间:2011-10-18 16:25:18

标签: c# generics

这是我正在尝试做的事情,甚至不确定是否可能......

我正在创建BaseViewModel<T>,我希望它接受从Entity继承的类型

考虑以下代码:

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
{

public T MyEntity;

public SomeMethod()
{
MyEntity.SomeEntityProperty = SomeValue;
}

}

所以,我想说我的T继承自Entity,因此我知道它会有SomeEntityProperty。

这可能吗?

4 个答案:

答案 0 :(得分:25)

Salvatore的回答是完全正确的,我只想更好地描述这个概念。

您需要的是“通用类型约束”;指定用作T的类型必须符合某些行为(例如从比Object更多派生的对象或接口派生),从而增加允许对该对象执行的操作而无需进一步转换(通常应避免)在仿制药中)。

正如Salvatore的回答所示,GTC使用“where”关键字定义:

public abstract class BaseViewModel<T> :
    NotificationObject,
    INavigationAware

    where T : Entity;
{
   ...

此GTC基本上声明任何T必须从实体派生(但是远程)。这允许您将T视为实体(除了实例化新Ts;需要额外的GTC),无论实际通用参数类型从实体派生的程度如何。您可以调用实体上显示的任何方法,并获取/设置任何字段或属性。

您还可以指定:

  • 类型必须是类(where T:class),或者必须是ValueType(where T:struct)。这允许或阻止比较和分配T实例为null,这也允许或阻止使用空合并运算符??
  • 该类型必须具有无参数构造函数(where T:new())。这允许使用new关键字实例化Ts,方法是在编译时确保用作Ts的所有类型都有一个不带参数的构造函数。

答案 1 :(得分:12)

public abstract class BaseViewModel<T> :
    NotificationObject,
    INavigationAware

    where T : Entity
{

    public T MyEntity;

    public SomeMethod()
    {
        MyEntity.SomeEntityProperty = SomeValue;
    }

}

答案 2 :(得分:5)

只需使用where关键字:

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
    where T:Entity
{
...

答案 3 :(得分:4)

尝试使用where约束:

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
    where T : Entity
{
    public T MyEntity;

    public SomeMethod()
    {
        MyEntity.SomeEntityProperty = SomeValue;
    }
}