C# - Múltiples tipos genéricos en una lista


Esto probablemente no es posible, pero tengo esta clase:

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

Hay más, pero vamos a mantenerlo simple. El tipo genérico (DataType) está limitado a los tipos de valor por la instrucción where. Lo que quiero hacer es tener una lista de estos objetos de metadatos de diferentes tipos (DataType). Tales como:

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

¿Es esto posible?

 117
Author: Carl, 2008-12-09

3 answers

public abstract class Metadata
{
}

// extend abstract Metadata class
public class Metadata<DataType> : Metadata where DataType : struct
{
    private DataType mDataType;
}
 148
Author: leppie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-05 00:44:15

Siguiendo la respuesta de leppie, ¿por qué no hacer MetaData una interfaz:

public interface IMetaData { }

public class Metadata<DataType> : IMetaData where DataType : struct
{
    private DataType mDataType;
}
 74
Author: bruno conde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-09 15:41:16

También he usado una versión no genérica, usando la palabra clave new:

public interface IMetadata
{
    Type DataType { get; }

    object Data { get; }
}

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

La implementación explícita de la interfaz se usa para permitir que ambos miembros 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; }
}

Podría derivar una versión orientada a tipos de valor:

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

Esto se puede extender a cualquier tipo de restricciones genéricas.

 26
Author: Bryan Watts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-20 23:41:01