2011-02-04 2 views
6

Проблема: У меня есть Dictionary<String, String>, что мне нужен псевдоним, но мне также нужно сериализовать/десериализовать его.C# Typedef, который сохраняет атрибуты

Решения, которые я пробовал:

class Foo : Dictionary<String, String> { } 

, но эту работу, потому что я должен был бы создать конструктор десериализации и это было бы немного глупо, когда словарь может быть уже десериализации.

Я также попытался

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

, но мне это нужно, чтобы работать в более чем один файл, а если добавить эту строку во всех файлах, которые нуждаются в этом, я буду извлекать половину точки определений типов (т.е. если мне нужно изменить тип, я могу сделать это легко)

Что я могу сделать с этим?

+0

Почему вам нужен псевдоним? Какую проблему вы пытаетесь решить? –

+0

Обычные причины для использования псевдонимов: чтобы я мог легко сделать его классом позже, если потребуется, и чтобы люди не пытались рассматривать его как неправильный тип словаря. Изменить: также, если мне нужно изменить ключ или значение на что-то другое, кроме строки, это легко. – Drew

+0

Является ли это сериализацией «BinaryFormatter»? или что? –

ответ

6

С атрибутами подхода alias сохранены, но вы заявляете, что слишком много служебных (per-file и т. Д.).

Тип уровня атрибутов являются genercally сохранились - но это зависит от атрибута - для [Serializable], обратите внимание, что у него есть:

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

Inherited = false значима - то есть она не передается по наследству.

Лично я, вероятно, сфокусировал бы внимание на том, что сериализация ctor/callbacks работает в первом примере - я сомневаюсь, что потребовалось бы гораздо больше усилий. Ниже кажется отлично:

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

Однако здесь альтернатива с помощью инкапсуляции:

[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

Ммм «что было бы немного глупо, когда словарь может быть уже десериализации.» Я бы не сказал, что глупо называть базовой CTOR в (почти) любом случае + это 1 мин усилие, так что я бы сказал, что это сделать ...

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

} 

или

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

}