Подтвердить что ты не робот

Вычисление параметров С#?

Можно ли изгнать аргументы param в С#? У меня есть:

Dictionary<string,object> dict;  // but I know all values are strings
string key, value;

Грубо говоря (и если у меня не было статического набора текста), я хочу сделать:

dict.TryGetValue(key, out value);

но это, очевидно, не будет компилироваться, потому что он "не может преобразовать из" out string "в" out object "".

Обходной путь, который я использую, это:

object valueAsObject;
dict.TryGetValue(key, out valueAsObject);
value = (string) valueAsObject;

но это кажется довольно неудобным.

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

4b9b3361

Ответ 1

Я не знаю, отличная идея, но вы можете добавить общий метод расширения:

    static bool TryGetTypedValue<TKey, TValue, TActual>(
        this IDictionary<TKey, TValue> data,
        TKey key,
        out TActual value) where TActual : TValue
    {
        TValue tmp;
        if (data.TryGetValue(key, out tmp))
        {
            value = (TActual)tmp;
            return true;
        }
        value = default(TActual);
        return false;
    }
    static void Main()
    {
        Dictionary<string,object> dict
            = new Dictionary<string,object>();
        dict.Add("abc","def");
        string key = "abc", value;
        dict.TryGetTypedValue(key, out value);
    }

Ответ 2

Если вы знаете, что все значения имеют значения, используйте Dictionary<string, string>. Тип параметра out задается типом второго типичного параметра типа. Поскольку ваш объект в настоящее время является объектом, он возвращает объект при извлечении из словаря. Если вы измените его на строку, он вернет строки.

Ответ 3

Нет, нет никакого способа обойти это. Параметр out должен иметь переменную, которая точно соответствует.

Использование строковой ссылки небезопасно, поскольку словарь может содержать другие вещи, кроме строк. Однако, если у вас есть словарь строк и вы пытаетесь использовать объектную переменную в вызове TryGetValue, это не сработает, даже если это будет безопасно. Тип переменной должен точно соответствовать.

Ответ 4

Я использовал метод расширения Marc, но добавил немного к нему.

Моя проблема с оригиналом заключалась в том, что в некоторых случаях мой словарь будет содержать int64, тогда как я ожидаю int 32. В других случаях словарь будет содержать строку (например, "42" ), в то время как я хотел бы ее получить как int.

Невозможно обработать преобразование в методе Marc, поэтому я добавил возможность передать делегат методу преобразования:

internal static bool TryGetTypedValue<TKey, TValue, TActual>(
        this IDictionary<TKey, TValue> data,
        TKey key,
        out TActual value, Func<TValue, TActual> converter = null) where TActual : TValue
    {
        TValue tmp;
        if (data.TryGetValue(key, out tmp))
        {
            if (converter != null)
            {
                value = converter(tmp);
                return true;
            }
            if (tmp is TActual)
            {
                value = (TActual) tmp;
                return true;
            }
            value = default(TActual);
            return false;
        }
        value = default(TActual);
        return false;
    }

Что вы можете назвать так:

int limit;
myParameters.TryGetTypedValue("limitValue", out limit, Convert.ToInt32)

Ответ 5

Нет, вы не можете. Код внутри метода напрямую изменяет переданную ему переменную, он не передает копию содержимого переменной.