Как я могу получить и установить общие значения со строковыми идентификаторами - PullRequest
0 голосов
/ 08 марта 2012

Я всегда бегаю кругами с этой проблемой.я написал код, который использует следующий интерфейс:

public interface IStorage
{
    T GetElement<T>(String id) where T : class;
    void SetElement<T>(String id, T element) where T : class;
}

Но я просто не в состоянии писать общие функции get и set.Я всегда пытаюсь получить доступ к словарям, но все мои попытки даже не компилируются.Я здесь что-то громоздкое, что это?

Ответы [ 2 ]

2 голосов
/ 08 марта 2012

Способ определения интерфейса, вызов метода в реализации интерфейса требует указания базового типа <T>. В этот момент вы могли бы также кастовать.

[Отредактировано в примечании] Кроме того, базовый класс для универсального метода ограничен отдельным методом, а не классом / интерфейсом, который, вероятно, был причиной вашего проблемы.

Прежде всего, я бы упростил ваш интерфейс до чего-то вроде этого:

public interface IStorage<T> where T : class
{
  T this[ string id ] { get ; set ; }
}

Тогда я бы реализовал что-то вроде:

public class Repository : IStorage<Widget>
{
  private IDictionary<string,Widget> backingStore = new Dictionary<string,Widget>() ;

  public Widget this[string id]
  {
  get
    {
      Widget instance ;
      bool   exists   = backingStore.TryGetValue(id, out instance ) ;
      return instance ; // null if the dictionary doesn't contain the key
    }
  set
    {
      if ( string.IsNullOrWhiteSpace(id) ) throw new ArgumentException("id") ;
      if ( value == null                 ) throw new ArgumentNullException("value") ;
      backingStore.Add( id , value ) ;
      return ;
    }
  }
}
1 голос
/ 08 марта 2012

Вы определенно можете делать то, что хотите, но вам нужно использовать что-то, кроме словаря. Ответ Николаса Кэри лучше сделать, но я уже начал с этого, поэтому я оставлю это на будущее, если кому-то действительно нужно знать, как использовать предоставленный вами интерфейс:

код

public interface IStorage
{
    T GetElement<T>(string id) where T : class;
    void SetElement<T>(string id, T element) where T : class;
}

public class StorageImpl : IStorage
{
    private Hashtable _hashTable = new Hashtable();

    public T GetElement<T>(string id) where T : class
    {
        var hashObject = _hashTable[id];

        if (hashObject.GetType() == typeof(T))
        {
            return (T)hashObject;
        }
        else
        {
            throw new Exception(
                String.Format("Item ID: {0} was of type {1}. Expecting type {2}",
                    id, hashObject.GetType(), typeof(T)));
        }   
    }

    public void SetElement<T>(string id, T element) where T : class
    {
        lock (_hashTable.SyncRoot)
        {
            _hashTable[id] = element;
        }
    }
}

public static void RunSnippet()
{
    IStorage storage = new StorageImpl();

    storage.SetElement<string>("something", "string object");
    storage.SetElement<Exception>("someexception", new Exception("some exception message"));

    Console.WriteLine(storage.GetElement<string>("something"));
    Console.WriteLine(storage.GetElement<Exception>("someexception").Message);
    // Throws exception
    Console.WriteLine(storage.GetElement<string>("someexception"));
}

выход

string object
some exception message
---
The following error occurred while executing the snippet:
System.Exception: Item ID: someexception was of type System.Exception. Expecting type System.String
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...