2011-08-12 9 views
6

Yalnızca dizine alınabilen nesnelerin C# içindeki bir Sözlük içine depolanmasını sağlamak için bir yöntem arıyorum. Yalnızca Seri hale getirilebilir nesnelerle birlikte verilen sözlük

Ben buna benzer bir şey yapmak arıyorum daha spesifik olmak gerekirse:

Dictionary<String, ISerializable> serialDict = new Dictionary<String, ISerializable>(); 

bu sorun ben tamsayılar, Boolean, ya dizeleri gibi ilkel türleri saklamaz olmasıdır.

Sözlüğümün yalnızca serileştirilebilecek nesneler içerdiğinden emin olmanın bir yolu var mı?

cevap

4

Bunu derleme zamanında yapabileceğinizi sanmıyorum, ancak bunu çalışma zamanında yapabilirsiniz. Kendi sınıfınızı Dictionary<TKey, TValue>'dan türeterek oluşturuyorsanız, sınıfınızın yapıcısında, TValue türüne bağlı öznitelikleri kontrol edebilir ve bunlardan biri olan SerializableAttribute olduğundan emin olabilirsiniz, bir istisna atarsınız.

Tüm standart ilkel türleri (int, bool vb.) Bu özniteliğe sahiptir.

+0

C#: Using Reflection to Instantiate a Generic Class in .Net içgörü için teşekkür ederiz, bu daha mantıklı. Bir derleme zamanı çözümü umuyordum ama bu gayet iyi çalışıyor. – LamdaComplex

0

Sözlüğünüzü sarmaya ne dersiniz? Bu şekilde

class SomeClass { 

    Dictionary<string,object> d; 
    // add ISerializable 
    public void Add(string key, ISerializable value) { 
     d[key] = value; 
    } 
    // add primitive types 
    public void Add(string key, bool value) { 
     d[key] = value; 
    } 
    public void Add(string key, int value) { 
     d[key] = value; 
    } 
    // etc ... 
} 

sadece ıserializable nesneleri ve ilkel tipleri eklenebilir eminiz. dikkate almak

+1

MSDN belgelerine göre, nesneler yalnızca seri hale getirme işlemini denetlemek istiyorlarsa ISerializable arabirimini uygulamalıdır. Bu nedenle, tüm seri hale getirilebilir nesneler bu arabirimi uygulamaz. – R0MANARMY

1
[Serializable] 
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue> 
{ 
    static SerializableDictionary() 
    { 
     AssertSerializable(typeof(TKey)); 
     AssertSerializable(typeof(TValue)); 
    } 

    static void AssertSerializable(Type t) 
    { 
     if (!t.IsSerializable) 
     { 
      throw new NotSupportedException(string.Format(
       "{0} is not serializable", t.Name)); 
     } 
    } 
} 
+1

Bu Sözlükteki bobinleri ve bobinleri saklamak istendiyse, TV Türü olarak ne Tür seçilmelidir? –

+0

@David İyi nokta, +1. Bu desteklenmiyor. Ama sorumu, askerden birinin bir kombinasyonunu değil, bu tiplerden birini depolamak istiyormuş gibi okudum. –

2

Bir şey bir arabirim uygulamak yerine seri hale getirilebilir sınıflarında SerializableAttribute ile etiketlenmiş olmasıdır. MSDN Gönderen:

SerializableAttribute ile işaretlenmiş olmalıdır serileştirilebilir olabilecek her sınıfı. Bir sınıf serileştirme işlemini denetlemek gerekiyorsa, ISerializable arabirimini uygulayabilir.

Eğer o değil eğer geçirilen eleman bir seri hale getirilebilir niteliği olup olmadığını kontrol etmek IDictioanry arayüzü ve her zaman birileri eklemek çağırır, kullanım yansıma uygulayan kendi sınıf yapmak (ve bir istisna yapmak gerekir hangi 't).

Kod bir SerializablePrimative sarıcı sınıfı oluşturmak olacaktır

class MyDictionary<TKey, TValue> : IDictionary<TKey, TValue> 
{ 
    private Dictionary<TKey, TValue> d; 

    public void Add(TKey key, TValue value) 
    { 
     if(value.GetType().IsSerializable) 
     { 
      d.Add(key, value); 
     } 
     else 
     { 
      throw new ArgumentException(); 
     } 
    } 
    ..... 
} 
+0

Bu çözümü beğendim, projem için ihtiyacım olan şey. Teşekkür ederim. – LamdaComplex

1

Bir cevap gibi görünecektir.

class SerializablePrimative<T> : ISerializable { 
    private T val = default(); 

    private SerializablePrimative(T newVal){ 
     val = newVal; 
    } 

    public static boolean IsSupported(Object o){ 
     if (o == null){ 
      return false; 
     }else{ 
      return IsSupported(o.GetType()); 
     } 
    } 

    public static boolean IsSupported(Type t){ 
     if (// you want to support* ...) 
     { 
      return true; 
     } 
     else 
     { 
     return false; 
     } 
    } 

    public static SerializablePrimative GetSerializable(Object o){ 
     if (IsSupported(o)){ 
      return //Intstatiate via Reflection ** 
     }else { 
      return null; 
     } 
    } 
} 

dinlenme okuyucuya bir alıştırma olarak bırakılmıştır, ama temelde senin bu belirli türde yapmak için bir adaptör yaratıyor senin sözlüğü "fit".

* Ayrıca Bakınız: Types Supported by the Data Contract Serializer

** Ayrıca Bakınız:

+0

Bu, seri hale getirilebilir sınıflar (ilkel değerler dahil) verilen overkill'ler zaten uygun özelliklerle etiketlenmiş gibi görünüyor. – R0MANARMY

İlgili konular