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

发布于 2024-12-10 17:46:19 字数 430 浏览 0 评论 0原文

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

我正在创建 BaseViewModel 并且我希望它接受从 Entity 继承的类型

考虑这段代码:

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

public T MyEntity;

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

}

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

这可能吗?

Here is what I'm trying to do, not even sure if possible..

I'm creating BaseViewModel<T> and I want it to accept types inherited from Entity

Consider this code:

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

public T MyEntity;

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

}

So, I want to say that my T inherited from Entity and therefore I KNOW that it will have SomeEntityProperty.

Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

魂归处 2024-12-17 17:46:19

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

你需要的是“通用类型约束”;指定用作 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 合并运算符 ??
  • 该类型必须具有无参数构造函数(其中 T:new())。这允许使用 new 关键字实例化 Ts,方法是确保在编译时用作 Ts 的所有类型都具有不带参数的构造函数。

Salvatore's answer is totally correct, I just wanted to describe the concept a little better.

What you need is a "generic type constraint"; to specify that the type used as T must conform to certain behaviors (such as being derived from an object or interface more derived than Object), thus increasing what you are allowed to do with that object without further casting (which is generally to be avoided in generics).

As Salvatore's answer shows, GTCs are defined using the "where" keyword:

public abstract class BaseViewModel<T> :
    NotificationObject,
    INavigationAware

    where T : Entity;
{
   ...

This GTC basically states that any T must derive (however remotely) from Entity. This allows you to treat T as if it were an Entity (except for instantiation of new Ts; that requires an additional GTC), regardless of how more or less derived the actual generic parameter type is from Entity. You can call any method that appears on Entity, and get/set any field or property.

You can also specify that:

  • The type must be a class (where T:class), or alternately must be a ValueType (where T:struct). This either permits or prevents comparison and assignment of a T instance to null, which also allows or prevents use of the null-coalescing operator ??.
  • The type must have a parameterless constructor (where T:new()). This allows instantiations of Ts using the new keyword, by ensuring at compile-time that all types used as Ts have a constructor that takes no parameters.
羁客 2024-12-17 17:46:19
public abstract class BaseViewModel<T> :
    NotificationObject,
    INavigationAware

    where T : Entity
{

    public T MyEntity;

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

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

    where T : Entity
{

    public T MyEntity;

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

}
Hello爱情风 2024-12-17 17:46:19

尝试使用 where 约束:

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

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

Try using the where constraint:

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

    public SomeMethod()
    {
        MyEntity.SomeEntityProperty = SomeValue;
    }
}
逆蝶 2024-12-17 17:46:19

只需使用 where 关键字:

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

Just use the where keyword:

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
    where T:Entity
{
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文