Как получить делегат, возвращенный из iDictionary? - PullRequest
0 голосов
/ 16 августа 2011

Я пытаюсь использовать словарь для ссылки на делегата, но я получаю ошибку, когда пытаюсь получить указатель делегата. Для большего контекста мне дают строку для поиска значения в C-структуре. Я написал методы для получения / установки данных в структуре C, но теперь мне нужно вызывать методы с заданной строкой. Если у вас есть лучший способ, пожалуйста, дайте мне знать.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestCode
{
    public class tuboFillLinePresets
    {
        public IDictionary<string, object> DBLookup { get;  set; }
        public config_data Data;

        delegate float MyDel(int chan);

        public float ChanGain(int chan)
        {
            return Data.ChannelGain(chan);
        }

        public float MagCurr(int chan)
        {
           return Data.MagCurrent(chan);
        }

        public tuboFillLinePresets()
        {
            DBLookup = new Dictionary<string, object>();
            MyDel cg = new MyDel(ChanGain);
            MyDel mc = new MyDel(MagCurr);
            DBLookup.Add("HBGain", cg);
            DBLookup.Add("LBGain", cg);
            DBLookup.Add("MagCurrent", mc);
        }

        public LinePresets tuboGetLinePresets(LinePresets LinePresets)
        {
           foreach (var item in LinePresets.Parameters)
           {
               String s = item.Key;
               MyDel func;
               DBLookup.TryGetValue(s, out func);  // error here 
               LinePresets.Parameters[s] = func(3);
           }
           return LinePresets;
       }
   }
}

Ответы [ 4 ]

6 голосов
/ 16 августа 2011

Ваше поле DBLookup должно быть Dictionary<string, MyDel>. Таким образом, при получении значения возвращаемый тип будет MyDel, а не object.

Вы получаете ошибку, потому что тип ссылки, которую вы передаете как аргумент out, должен совпадать с типом параметра точно . Поскольку аргумент out имеет тип MyDel, а параметр TryGetValue имеет значение object (поскольку это тип значения в вашем словаре), вы получите ошибку. После внесения вышеуказанного изменения тип аргумента будет соответствовать типу параметра, и сообщение об ошибке исчезнет.

В общем, если вы обнаружите, что объявляете словарь, содержащий значения object, подумайте, что вы на самом деле будете хранить, и посмотрите, можете ли вы использовать другой тип.

1 голос
/ 17 августа 2011

В вашем словаре хранится objects, а не экземпляры MyDel.Потому что это было бы вполне возможно для вас:

DBLookup.Add("foo", "HAH!");

Компилятор не позволит вам передать переменную как out, которая не может содержать любое значение, которое может содержать словарь.У вас есть два варианта:

  • Изменить свой словарь на Dictionary<string, MyDel> (это лучший вариант, если в словаре действительно хранятся только экземпляры MyDel со строковым ключом)
  • Используйте промежуточную переменную для извлечения

Примерно так:

object value;

if(DBLookup.TryGetValue(s, out value) && value is MyDel)
{
    func = (MyDel)value;
    LingPresents.Parameters[s] = func(3)
}
1 голос
/ 17 августа 2011

определите ваш словарь как

public IDictionary<string, MyDel> DBLookup { get;  set; }

и соответственно измените остальную часть кода ...

0 голосов
/ 17 августа 2011

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

...