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

kat*_*tit 17 c# generics

这是我想要做的,甚至不确定是否可能..

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

考虑以下代码:

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

public T MyEntity;

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

}
Run Code Online (Sandbox Code Playgroud)

所以,我想说我T继承了Entity,因此我知道它会有SomeEntityProperty.

这可能吗?

Kei*_*thS 26

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

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

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

public abstract class BaseViewModel<T> :
    NotificationObject,
    INavigationAware

    where T : Entity;
{
   ...
Run Code Online (Sandbox Code Playgroud)

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

您还可以指定:

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


Sal*_*iti 12

public abstract class BaseViewModel<T> :
    NotificationObject,
    INavigationAware

    where T : Entity
{

    public T MyEntity;

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

}
Run Code Online (Sandbox Code Playgroud)


Kie*_*ron 6

尝试使用where约束:

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

    public SomeMethod()
    {
        MyEntity.SomeEntityProperty = SomeValue;
    }
}
Run Code Online (Sandbox Code Playgroud)


bri*_*ler 5

只需使用where关键字:

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
    where T:Entity
{
...
Run Code Online (Sandbox Code Playgroud)