2011-02-04 18 views
6

Problem: Mam Dictionary<String, String>, do którego potrzebuję aliasu, ale muszę również serializować/deserializować go.C# Typedef, który zachowuje atrybuty

Solutions próbowałem:

class Foo : Dictionary<String, String> { } 

ale że praca bo musiałbym stworzyć konstruktor deserializacjia i że będzie to trochę głupie, gdy słownik już można rozszeregować.

Próbowałem też

using Foo = System.Collections.Generic.Dictionary<String, String>; 

ale muszę to do pracy w więcej niż jednym pliku, a jeśli dodać tę linię we wszystkich plikach, które jej potrzebują, będę usuwając pół punktu typedefs (czyli to, jeśli muszę zmienić typ, mogę to zrobić z łatwością)

Co mogę z tym zrobić?

+0

Dlaczego potrzebujesz aliasu? Co problwm próbujesz rozwiązać? –

+0

Zwykłe powody, dla których potrzebujemy aliasów: Aby w razie potrzeby móc z łatwością uczynić z nich klasę, tak aby ludzie nie próbowali traktować jej jako niewłaściwego typu słownika. Edycja: również, jeśli muszę zmienić klucz lub wartość na coś innego niż ciąg jest łatwe. – Drew

+0

Czy to jest serializacja 'BinaryFormatter'? lub które? –

Odpowiedz

6

Przy atrybutach podejścia aliasy są zachowywane, ale można stwierdzić, że jest to zbyt duży narzut (na plik itp.).

typu poziom atrybutów genercally zachowane - ale to zależy od atrybutu - dla [Serializable], trzeba pamiętać, że ma:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct 
| AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)] 

Inherited = false jest znacząca - to znaczy, że nie jest dziedziczona.

Osobiście prawdopodobnie skupiłbym się na tym, aby w pierwszym przykładzie wykonać ctorowanie/wywołanie zwrotne serializacji - wątpię, czy wymagałoby to znacznie więcej wysiłku. Dodaje się wydaje dobrze:

[Serializable] 
public class Foo: Dictionary<string, string> { 
    public Foo() : base() { } 
    public Foo(SerializationInfo info, StreamingContext context) : base(info, context) { } 
    public Foo(int capacity) : base(capacity) { } 
    public Foo(IEqualityComparer<string> comparer): base(comparer) {} 
    public Foo(IDictionary<string,string> dictionary) : base(dictionary) { } 
    public Foo(int capacity, IEqualityComparer<string> comparer) : base(capacity, comparer) { } 
    public Foo(IDictionary<string, string> dictionary, IEqualityComparer<string> comparer) : base(dictionary, comparer) { } 
} 

Jednak tutaj jest alternatywą poprzez enkapsulacji: „To byłoby trochę głupio, gdy słownik już można rozszeregować”

[Serializable] 
public class Foo : IDictionary<string,string> 
{ 
    private readonly Dictionary<string, string> inner = new Dictionary<string, string>(); 

    public void Add(string key, string value) 
    { 
     inner.Add(key, value); 
    } 

    public bool ContainsKey(string key) 
    { 
     return inner.ContainsKey(key); 
    } 

    public ICollection<string> Keys 
    { 
     get { return inner.Keys; } 
    } 

    public bool Remove(string key) 
    { 
     return inner.Remove(key); 
    } 

    public bool TryGetValue(string key, out string value) 
    { 
     return inner.TryGetValue(key, out value); 
    } 

    public ICollection<string> Values 
    { 
     get { return inner.Values; } 
    } 

    public string this[string key] 
    { 
     get 
     { 
      return inner[key]; 
     } 
     set 
     { 
      inner[key] = value; 
     } 
    } 

    void ICollection<KeyValuePair<string, string>>.Add(KeyValuePair<string, string> item) 
    { 
     ((IDictionary<string,string>)inner).Add(item); 
    } 

    public void Clear() 
    { 
     inner.Clear(); 
    } 

    bool ICollection<KeyValuePair<string, string>>.Contains(KeyValuePair<string, string> item) 
    { 
     return ((IDictionary<string, string>)inner).Contains(item); 
    } 

    void ICollection<KeyValuePair<string, string>>.CopyTo(KeyValuePair<string, string>[] array, int arrayIndex) 
    { 
     ((IDictionary<string, string>)inner).CopyTo(array, arrayIndex); 
    } 

    public int Count 
    { 
     get { return inner.Count; } 
    } 

    bool ICollection<KeyValuePair<string, string>>.IsReadOnly 
    { 
     get { return ((IDictionary<string, string>)inner).IsReadOnly; } 
    } 

    bool ICollection<KeyValuePair<string, string>>.Remove(KeyValuePair<string, string> item) 
    { 
     return ((IDictionary<string, string>)inner).Remove(item); 
    } 

    public IEnumerator<KeyValuePair<string, string>> GetEnumerator() 
    { 
     return inner.GetEnumerator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return inner.GetEnumerator(); 
    } 
} 
1

Mmm Nie powiedziałbym, że to głupie, aby wywołać konstruktor bazowy w (prawie) każdym przypadku + to 1 min wysiłku, więc powiedziałbym to zrobić ...

[Serializable] 
public class Foo : Dictionary<string, string> 
{ 
    public Foo() 
     : base() 
    { 
    } 
    public Foo(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 

} 

lub

[Serializable] 
public class Foo<TKey,TValue> : Dictionary<TKey,TValue> 
{ 
    public Foo() 
     : base() 
    { 
    } 
    public Foo(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 

}