web-dev-qa-db-fra.com

C # - Plusieurs types génériques dans une liste

Ce n'est probablement pas possible, mais j'ai ce cours:

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

Il y a plus que cela, mais restons simples. Le type générique (DataType) est limité aux types de valeur par l'instruction where. Ce que je veux faire, c'est avoir une liste de ces objets de métadonnées de différents types (DataType). Tel que:

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

Est-ce seulement possible?

134
Carl
public abstract class Metadata
{
}

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

Après la réponse de leppie, pourquoi ne pas faire de MetaData une interface:

public interface IMetaData { }

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

J'ai également utilisé une version non générique, en utilisant le mot clé new:

public interface IMetadata
{
    Type DataType { get; }

    object Data { get; }
}

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

L'implémentation d'interface explicite est utilisée pour autoriser les deux membres 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; }
}

Vous pouvez dériver une version ciblant des types de valeur:

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

Cela peut être étendu à tout type de contraintes génériques.

28
Bryan Watts