Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.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#_Generics - Fatal编程技术网

C#-一个列表中有多个泛型类型

C#-一个列表中有多个泛型类型,c#,generics,C#,Generics,这可能是不可能的,但我有一门课: public class Metadata<DataType> where DataType : struct { private DataType mDataType; } 数据类型为struct的公共类元数据 { 私有数据类型mDataType; } 还有很多,但让我们保持简单。where语句将泛型类型(数据类型)限制为值类型。我想做的是列出这些不同类型(数据类型)的元数据对象。例如: List<Metadata> met

这可能是不可能的,但我有一门课:

public class Metadata<DataType> where DataType : struct
{
    private DataType mDataType;
}
数据类型为struct的公共类元数据 { 私有数据类型mDataType; } 还有很多,但让我们保持简单。where语句将泛型类型(数据类型)限制为值类型。我想做的是列出这些不同类型(数据类型)的元数据对象。例如:

List<Metadata> metadataObjects;
metadataObjects.Add(new Metadata<int>());
metadataObjects.Add(new Metadata<bool>());
metadataObjects.Add(new Metadata<double>());
列出元数据对象;
添加(新元数据());
添加(新元数据());
添加(新元数据());
这可能吗?

公共抽象类元数据
public abstract class Metadata
{
}

// extend abstract Metadata class
public class Metadata<DataType> : Metadata where DataType : struct
{
    private DataType mDataType;
}
{ } //扩展抽象元数据类 公共类元数据:元数据,其中数据类型:struct { 私有数据类型mDataType; }
按照leppie的回答,为什么不将
元数据
作为一个接口:

public interface IMetaData { }

public class Metadata<DataType> : IMetaData where DataType : struct
{
    private DataType mDataType;
}
公共接口IMetaData{}
公共类元数据:IMetaData,其中数据类型:struct
{
私有数据类型mDataType;
}

我还使用了非通用版本,使用了
新的
关键字:

public interface IMetadata
{
    Type DataType { get; }

    object Data { get; }
}

public interface IMetadata<TData> : IMetadata
{
    new TData Data { get; }
}
您可以派生针对以下类型的值的版本:

public interface IValueTypeMetadata : IMetadata
{

}

public interface IValueTypeMetadata<TData> : IMetadata<TData>, IValueTypeMetadata where TData : struct
{

}

public class ValueTypeMetadata<TData> : Metadata<TData>, IValueTypeMetadata<TData> where TData : struct
{
    public ValueTypeMetadata(TData data) : base(data)
    {}
}
公共接口IValueTypeMetadata:IMetadata
{
}
公共接口IValueTypeMetadata:IMetadata,IValueTypeMetadata其中TData:struct
{
}
公共类ValueTypeMetadata:Metadata,IValueTypeMetadata其中TData:struct
{
public ValueTypeMetadata(TData数据):数据库(数据)
{}
}

这可以扩展到任何类型的通用约束。

Wow!我真的认为那是不可能的!你是个救生员,伙计+10英镑!我不知道这是为什么。。正是我需要的!我有一个类似的问题,但我的泛型类是从另一个泛型类扩展而来的,所以我无法使用您的解决方案。。。对于这种情况的修复方法有什么想法吗?与简单的
列表相比,这种方法是否有好处?请看我在OP的问题下发表的评论。@SaebAmini列表不会向开发人员显示任何意图,也不会阻止开发人员通过错误地向列表中添加一些非元数据对象来攻击自己。通过使用列表,可以理解列表应该包含什么。最有可能的元数据将具有一些公共属性/方法,这些属性/方法在上述示例中没有显示。通过对象访问这些对象需要一个繁琐的强制转换。有人能告诉我为什么这种方法更好吗?因为没有共享的公共功能-那么为什么要浪费一个基类呢?一个接口就足够了,因为您可以在结构中实现接口。然而,使用虚拟方法的类继承大约比接口方法快1.4倍。因此,如果您计划在元数据中实现任何非通用元数据(虚拟)方法/属性,那么如果性能是一个问题,请选择抽象类而不是接口。否则,使用接口可能会更灵活。+1仅仅因为您正在演示如何使用它(
DataType
objectdata
帮助很大),我似乎无法编写示例
反序列化(metadata.Data)。它告诉我无法解析符号元数据。如何检索数据类型以将其用于泛型方法?我想知道与仅使用
列表相比,下面答案中的方法是否有任何真正的好处?它们不会停止装箱/拆箱,也不会消除强制转换的需要,最终,您会得到一个
元数据
对象,它不会告诉您任何有关实际
数据类型的信息,我正在寻找解决这些问题的解决方案。如果要声明接口/类,只是为了能够将实现/派生的泛型类型放入泛型列表中,这与使用
列表
有多大不同,除了有一个无意义的层之外?抽象基类和接口都通过限制可以添加到列表中的元素类型来提供一定程度的控制。我也看不出拳击是如何做到这一点的。当然,如果您使用的是.NETV4.0或更高版本,那么协方差就是解决方案<代码>列表
起作用。@0b101010我也这么想,但不幸的是,值类型不允许有差异。因为OP有一个
struct
约束,所以它在这里不起作用@0b101010,两者都只限制引用类型,仍然可以添加任何内置值类型和任何结构。另外,最后,您有一个
元数据
引用类型的列表,而不是原始值类型,没有关于每个元素的底层值类型的(编译时)信息,这实际上是“装箱”。
public interface IValueTypeMetadata : IMetadata
{

}

public interface IValueTypeMetadata<TData> : IMetadata<TData>, IValueTypeMetadata where TData : struct
{

}

public class ValueTypeMetadata<TData> : Metadata<TData>, IValueTypeMetadata<TData> where TData : struct
{
    public ValueTypeMetadata(TData data) : base(data)
    {}
}