Созданный экземпляр в методе расширения имеет значение null - PullRequest
2 голосов
/ 01 августа 2011

Я создал этот метод расширения

public static void AddIfNullCreate<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
 {
     if (dictionary == null)
     {
         dictionary = new Dictionary<TKey, TValue>();
     }

     dictionary.Add(key, value);
 }

Но когда я использую это

    public void DictionaryTest()
    {
        IDictionary<int, string> d = GetD();

        d.AddIfNullCreate(1,"ss");
    }

    private IDictionary<int, string> GetD()
    {
        return null;
    }

После вызова AddIfNullCreate имеет значение null. Почему это так?

Ответы [ 2 ]

8 голосов
/ 01 августа 2011

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

Один из вариантов - вернуть словарь:

public static IDictionary<TKey, TValue> AddIfNullCreate<TKey, TValue>
    (this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
    if (dictionary == null)
    {
        dictionary = new Dictionary<TKey, TValue>();
    }

    dictionary.Add(key, value);
    return dictionary;
}

Тогда:

d = d.AddIfNullCreate(1, "ss");

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

public void DictionaryTest()
{
    IDictionary<int, string> d = GetD() ?? new Dictionary<int, string>();

    d[1] = "ss";
}
3 голосов
/ 01 августа 2011

Если бы это было сделано как обычный метод, вам нужно было бы передать словарь в качестве параметра ref, чтобы указатель памяти на вновь созданный объект был установлен правильно. Я не думаю, что вам будет разрешено указывать первый параметр метода расширения как параметр ref.

...