2008-12-09 19 views
105

Bu muhtemelen mümkün değildir, ancak bu sınıf var:C# - tek bir listede birden çok genel türler

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

fazlası var, ama en basit tutalım. Genel tür (DataType), nerede ifade tarafından değer türleri ile sınırlıdır. Yapmak istediğim, çeşitli türlerde (DataType) bu Meta Veri nesnelerinin bir listesine sahip olmak. Örneğin:

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

Bu mümkün mü?

public interface IMetaData { } 

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

Aşağıdaki cevaplarda yalnızca bir "Liste " listesi kullanılmasına kıyasla gerçek bir fayda olup olmadığını merak ediyorum? Boksu/kutucuklarını durdurmayacaklar, döküm ihtiyacını ortadan kaldırmayacaklar ve sonuçta, 'DataType' ile ilgili bir şey söylemeyen bir 'Metadata' nesnesini alıyorsunuz. Bu sorunları ele al. Eğer bir arayüz/sınıf ilan edecekseniz, sadece jenerik bir listeye uygulama/türetilmiş jenerik türünü koyabilmek adına, sadece _how different_, anlamsız bir katmana sahip olmaktan başka bir 'List ' kullanmaktan ibarettir. ? –

+8

Hem soyut taban sınıfı hem de arabirim, listeye eklenebilecek öğelerin türünü kısıtlayarak bir derece denetim sağlar. Boksun buna nasıl geldiğini de göremiyorum. – 0b101010

+1

Elbette, eğer .NET v4.0 veya üstünü kullanıyorsanız, o zaman kovaryans çözümdür. 'List >' hile yapar. – 0b101010

cevap

139
public abstract class Metadata 
{ 
} 

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

Vay! Bunun mümkün olduğunu düşünmemiştim! Sen bir hayat kurtarıcısın dostum! Bunun için – Carl

+2

+10! Neden bu derler bilmiyorum .. Tam olarak ihtiyacım olan şey! – Odys

+0

Benzer bir sorunum var, ancak genel sınıfım başka bir genel sınıftan uzanıyor, bu yüzden çözümünüzü kullanamıyorum ... bu durumla ilgili bir fikre ilişkin herhangi bir fikir var mı? – Sheridan

69

, neden MetaData bir arabirim yapmaz Data üyelerine izin vermek için kullanılır:

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; } 
} 

Sen değer türlerini hedefleyen bir sürümünü elde edebileceğini: Bu genel kısıtlamaları her türlü uzatılabilir

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

.

+0

Birisi bana bu yaklaşımın neden daha iyi olduğunu söyler mi? – Lazlo

+24

Ortak işlevler paylaşılmadığından Bunun üzerine bir sınıf yeterlidir – flq

+2

Bir arabirim yapıları arayüzde uygulayabildiğinizden, –

25

Ben de new anahtar kelimeyi kullanarak, bir genel olmayan versiyonunu kullandık:

public interface IMetadata 
{ 
    Type DataType { get; } 

    object Data { get; } 
} 

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

Açık arabirim uygulaması leppie cevabı takiben

+4

+1 sadece nasıl kullanıldığını gösteriliyorsunuz ('DataType' ve' Nesne Veri 'çok yardımcı oldu] – Odys

+4

Örneğin yazabilmek mümkün görünmüyor' Deserialize < metadata.DataType> (metadata.Data); '. Bana söyler * sembol meta verilerini çözemez *. Genel bir yöntem için kullanmak için DataType nasıl alınır? –

İlgili konular