Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#尝试将数组索引与泛型类型一起使用_C#_Arrays_Generics - Fatal编程技术网

C#尝试将数组索引与泛型类型一起使用

C#尝试将数组索引与泛型类型一起使用,c#,arrays,generics,C#,Arrays,Generics,所以,我已经找到了我问题一半的几个答案,但我试图结合的两个部分似乎以其他人以前从未遇到过的方式将事情组合在一起(或者至少他们没有发布相关信息) 我的目标是能够像这样使用我的代码: ModelFactory[DataModelX].DataY 我知道我能得到的是: ModelFactory.Get<DataModelX>.DataY 等等 但是,当我尝试键入ModelFactory.ModelFactory[DataModelX]。时,我无法访问ModelFacto

所以,我已经找到了我问题一半的几个答案,但我试图结合的两个部分似乎以其他人以前从未遇到过的方式将事情组合在一起(或者至少他们没有发布相关信息)

我的目标是能够像这样使用我的代码:

    ModelFactory[DataModelX].DataY
我知道我能得到的是:

    ModelFactory.Get<DataModelX>.DataY
等等

但是,当我尝试键入
ModelFactory.ModelFactory[DataModelX]。
时,我无法访问ModelFactory。该属性显然是公共的,并且包含在适当的类中。另外,我不能将类作为参数传递(当然),但我不知道如何调整数组索引上的参数以接受类作为参数

施工:

  • ModelFactory应该是静态类或单例
  • 数据模型是所有实现IDataModel的类
  • 每个数据模型的数据属性都是唯一的
  • 您可以使用
    typeof(T)
    来获取泛型参数
    T
    的类型描述

    T newModel = (T)CreateModel(typeof(T));
    
    如果类型参数总是描述与
    T
    相同的类型,则不需要额外的类型参数

    T newModel = (T)CreateModel(typeof(T));
    
    您还可以使用字典而不是列表来存储模型

    private readonly Dictionary<Type,IDataModel> _models = new Dictionary<Type,IDataModel>();
    

    类的泛型类型参数具有误导性,因为它似乎暗示您将为每个模型类型创建一个工厂。放下它

    此外,您不能实现
    IReadOnlyList
    ,因为它要求索引为
    int
    。放下它

    public class ModelFactory { ... }
    
    现在您有两个选择:

  • 让索引器或普通Get方法返回
    IDataModel
    ,然后强制转换结果

    var m=(MyModelType)factory.Get(typeof(MyModelType))

    var m=(MyModelType)工厂[typeof(MyModelType)]

  • 声明一个get(但没有类的泛型类型参数!)。索引器不能具有泛型类型参数

  • public T Get():其中T:IDataModel
    {
    …(同上)
    回归(T)模型;
    }
    
    称之为

    var m = factory.Get<MyModelType>();
    
    var m=factory.Get();
    
    您可以使用
    typeof(T)
    来获取通用参数
    T
    的类型描述

    T newModel = (T)CreateModel(typeof(T));
    
    如果类型参数总是描述与
    T
    相同的类型,则不需要额外的类型参数

    T newModel = (T)CreateModel(typeof(T));
    
    您还可以使用字典而不是列表来存储模型

    private readonly Dictionary<Type,IDataModel> _models = new Dictionary<Type,IDataModel>();
    

    类的泛型类型参数具有误导性,因为它似乎暗示您将为每个模型类型创建一个工厂。放下它

    此外,您不能实现
    IReadOnlyList
    ,因为它要求索引为
    int
    。放下它

    public class ModelFactory { ... }
    
    现在您有两个选择:

  • 让索引器或普通Get方法返回
    IDataModel
    ,然后强制转换结果

    var m=(MyModelType)factory.Get(typeof(MyModelType))

    var m=(MyModelType)工厂[typeof(MyModelType)]

  • 声明一个get(但没有类的泛型类型参数!)。索引器不能具有泛型类型参数

  • public T Get():其中T:IDataModel
    {
    …(同上)
    回归(T)模型;
    }
    
    称之为

    var m = factory.Get<MyModelType>();
    
    var m=factory.Get();
    
    虽然拥有它会很好,但不幸的是,你所要求的是不可能的

    实现此工厂有三种可能的方法,但没有一种可以满足您的要求:

    1) 您拥有的实现是一个通用的
    模型工厂,其中T:IDataModel
    。如前所述,
    ModelFactory
    将迫使您限制您的工厂采用单一类型-例如,您必须定义
    ModelFactory
    ModelFactory
    ,等等。无论如何,这是一个有问题的设计决策,但更重要的是,您只能输入和输出用于创建工厂的混凝土
    IDataModel
    类型。例如,您不能创建
    ModelFactory
    并从索引器获取
    DataModel2
    。因此,使用这种实现没有多大意义

    2) 非泛型的
    ModelFactory
    ,其索引器返回
    IDataModel
    。这是完全有效的,但您必须强制转换输出以获得具体类型。因此,使用索引器的调用语法应该是
    ((DataModel2)ModelFactory[DataModel2]).Cat
    ,或者
    (ModelFactory[DataModel2]作为DataModel2.Cat
    。在我看来,这比一般的
    Get()
    函数要难看得多

    3) 带有泛型索引器的非泛型
    ModelFactory
    ,例如
    public T this[Type Type],其中T:IDataModel
    。这与您想要的最接近,但不幸的是,根据当前(C#6)规则,这是明确不允许的。例如,请参见。但是,值得注意的是,您仍然无法让编译器自动将
    类型
    识别为
    t
    。您不能编写
    public t this[t type]
    ,因为这会将
    type
    解释为类型
    t
    的对象,也不能编写
    public t this[t]type
    或类似的东西,因为
    typeof(t)
    是类型
    type
    的对象。因此,您必须使用
    ModelFactory[typeof(DataModel2)].Cat调用索引器(仍然很难看!),并在内部执行运行时检查,以确保
    type
    确实是type
    T

    T newModel = (T)CreateModel(typeof(T));
    

    因此,最干净的选择是使用非泛型的
    ModelFactory
    ,它使用
    public T Get()从内部
    字典中检索
    IDataModel
    实现,其中T:IDataModel{…}

    虽然拥有它很好,但不幸的是,您所要求的是不可能的

    实现此工厂有三种可能的方法,但没有一种可以满足您的要求:

    (一)