【问题标题】:Specify generics class where T should be subclass of other type指定泛型类,其中 T 应该是其他类型的子类
【发布时间】:2018-04-03 04:35:34
【问题描述】:

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

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

考虑这段代码:

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

public T MyEntity;

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

}

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

这可能吗?

【问题讨论】:

    标签: c# generics


    【解决方案1】:

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

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

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

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

    此 GTC 基本上规定任何 T 都必须从实体派生(无论多么遥远)。这允许您将 T 视为一个实体(新 T 的实例化除外;这需要额外的 GTC),而不管实际的泛型参数类型如何或多或少地从实体派生。您可以调用实体上出现的任何方法,并获取/设置任何字段或属性。

    您还可以指定:

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

    【讨论】:

    • 抱歉删除了一个 6 年前的响应,但是如何指定特定的构造函数签名?例如T:新(整数,浮点数)。这是我能找到的关于此功能的唯一参考,编译器似乎不喜欢它,但如果确实有定义它的方法,它肯定是一个有用的约束。
    • @SebAndraos - 不可能;这是原始帖子中的错误。唯一与构造函数直接相关的通用约束是需要任何 T 的无参数构造函数的默认构造函数约束。您可以定义其他约束,以确保存在特定的构造函数(或工厂方法)签名,但它不会与“where T:new(int, string)”一样通用。
    【解决方案2】:
    public abstract class BaseViewModel<T> :
        NotificationObject,
        INavigationAware
    
        where T : Entity
    {
    
        public T MyEntity;
    
        public SomeMethod()
        {
            MyEntity.SomeEntityProperty = SomeValue;
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      只需使用where 关键字:

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

      【讨论】:

        【解决方案4】:

        尝试使用where 约束:

        public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
            where T : Entity
        {
            public T MyEntity;
        
            public SomeMethod()
            {
                MyEntity.SomeEntityProperty = SomeValue;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2017-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-08
          • 2022-10-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多