web-dev-qa-db-ja.com

C#-1つのリストに複数のジェネリック型

これはおそらく不可能ですが、私はこのクラスを持っています:

public class Metadata<DataType> where DataType : struct
{
    private DataType mDataType;
}

それだけではありませんが、シンプルにしましょう。ジェネリック型(DataType)は、whereステートメントによって値の型に制限されます。私がやりたいのは、さまざまなタイプ(DataType)のこれらのメタデータオブジェクトのリストです。といった:

List<Metadata> metadataObjects;
metadataObjects.Add(new Metadata<int>());
metadataObjects.Add(new Metadata<bool>());
metadataObjects.Add(new Metadata<double>());

これも可能ですか?

134
Carl
public abstract class Metadata
{
}

// extend abstract Metadata class
public class Metadata<DataType> : Metadata where DataType : struct
{
    private DataType mDataType;
}
172
leppie

Leppieの答えに続いて、なぜMetaDataをインターフェースにしないのですか:

public interface IMetaData { }

public class Metadata<DataType> : IMetaData where DataType : struct
{
    private DataType mDataType;
}
86
bruno conde

newキーワードを使用して、非汎用バージョンも使用しました。

public interface IMetadata
{
    Type DataType { get; }

    object Data { get; }
}

public interface IMetadata<TData> : IMetadata
{
    new TData Data { get; }
}

明示的なインターフェイス実装は、両方のDataメンバーを許可するために使用されます。

public class Metadata<TData> : IMetadata<TData>
{
    public Metadata(TData data)
    {
       Data = data;
    }

    public Type DataType
    {
        get { return typeof(TData); }
    }

    object IMetadata.Data
    {
        get { return Data; }
    }

    public TData Data { get; private set; }
}

値をターゲットとするバージョンを導出できます。

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)
    {}
}

これは、あらゆる種類の一般的な制約に拡張できます。

28
Bryan Watts