代码之家  ›  专栏  ›  技术社区  ›  Jeff

泛型类的访问属性

  •  -2
  • Jeff  · 技术社区  · 7 年前

    我有一个扩展BaseModel类的模型类。

    public abstract class BaseModel {
       public abstract string Name;
       public abstract string NamePlural;
       //....
    }
    
    public class Production : BaseModel
    {
       public string Name = "production";
       public string NamePlural = "productions";
       //....
    }
    

    在其他地方,我调用另一个使用basemodel作为泛型基础的类:

    public class Store {
        public BaseModel SomeMethod<T>()
            where T : BaseModel
        {
             // here I need to get the Name property and the NamePlural property
             T.NamePlural; // gives compile error "T Not valid in the given context
    
             // next try:
             var model = typeof(T);
             model.NamePlural; // simply doesn't exist (model.Name gives the name of the class, but not the property)
    
             // another strange try:
             BaseModel model = new T(); // haha....nope
    
             //....
             return something...;
        }
    }
    
    //usage:
    
    Store store = new Store();
    Production p = SomeMethod<Production>();
    

    所以 问题是 以下内容:
    有没有一种简单的方法来访问这些属性?
    我甚至试过 Assembly.GetTypes()..., ...

    或者我需要 另一个 这些答案中描述的genreric类: How to access Property of generic member in generic class 是吗?

    是的,我读过相关的问题 Access to properties of generic object Get property of generic class

    1 回复  |  直到 7 年前
        1
  •  4
  •   Olivier Jacot-Descombes    7 年前

    基本模型应该有属性,而不是字段。

    public abstract class BaseModel {
       public abstract string Name { get; }
       public abstract string NamePlural { get; }
       //....
    }
    

    必须重写抽象方法才能实现它们。

    public class Production : BaseModel
    {
       public override string Name => "production";
       // Same as:  public override string Name { get { return "production"; } }
    
       public override string NamePlural => "productions";
       //....
    }
    

    将对象传递给 SomeMethod 以下内容:

    public class Store {
        public BaseModel SomeMethod<T>(T model)
            where T : BaseModel
        {
            string name = model.Name;
            string namePlural = model.NamePlural;
            ...
        }
    }
    

    仅为了访问名称,不需要泛型类型参数,因为 Production 其他派生类继承这些名称。仍然可以将生产对象作为参数传递给方法:

    public class Store {
        public BaseModel SomeMethod(BaseModel model)
        {
            string name = model.Name;
            string namePlural = model.NamePlural;
            ...
        }
    }
    

    如果你想用 new 在泛型类型参数上,添加 新的 约束。这就迫使 T 要有默认构造函数,即没有参数的构造函数:

    public BaseModel SomeMethod<T>()
        where T : BaseModel, new
    {
        var model = new T();
        string name = model.Name;
        ...
    }
    

    如果你想给 生产 一个静态行为,你可以把它变成一个单体。在类型名或泛型类型名上,只能访问静态成员。因为静态成员不能是抽象的,也不能被继承,所以如果您想要继承和静态行为,那么singleton模式是一种方法。

    public class Production : BaseModel
    {
        public static readonly Production Instance = new Production();
    
        private Production() // makes it non-instantiatable form outside.
        { }
    
        ...
    }
    

    你会用这个

    store.SomeMethod(Production.Instance);