2011-02-04 8 views
6

El problema: Tengo Dictionary<String, String> al que necesito un alias, pero también necesito serializarlo/deserializarlo.C# Typedef que conserva los atributos

Soluciones que he probado:

class Foo : Dictionary<String, String> { } 

pero ese trabajo porque yo tendría que crear un constructor Deserialización y que iba a ser un poco tonto cuando diccionario ya se puede deserializar.

También probé

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

pero necesito que esto funcione en más de un archivo y si añadir que en la línea de todos los archivos que lo necesitan, voy a estar quitando la mitad del punto de typedefs (que es, si necesito cambiar el tipo, puedo hacerlo fácilmente)

¿Qué puedo hacer al respecto?

+0

¿Por qué necesitas un alias? ¿Qué problwm estas tratando de resolver? –

+0

Las razones habituales para necesitar alias: para poder convertirlo en una clase más adelante si fuera necesario, y para que la gente no intente tratarlo como el tipo incorrecto de diccionario. Editar: también si tengo que cambiar la clave o el valor en algo que no sea una cadena, es fácil. – Drew

+0

¿Es esta serialización 'BinaryFormatter'? o cual? –

Respuesta

6

Con el alias los atributos de aproximación se conservan, pero usted declara que hay demasiada sobrecarga (por archivo, etc.). atribuye

Tipo de nivel se conservan genercally - pero depende del atributo - para [Serializable], tenga en cuenta que tiene:

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

la Inherited = false siendo significativa - es decir, que no se hereda.

Personalmente, probablemente me hubiera centrado en hacer funcionar el ctor/callbacks de serialización en el primer ejemplo - dudo que hubiera necesitado mucho más esfuerzo. El siguiente parece estar bien:

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

Sin embargo, aquí es una alternativa a través de la encapsulación:

[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 "que sería un poco tonto cuando diccionario ya se puede deserializar." Yo no diría que es una tontería para llamar a un ctor de base en (casi) todo caso + es 1 min esfuerzo, así que diría que lo haga ...

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

} 

o

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

} 
Cuestiones relacionadas