Объявите универсальный делегат, который получает с параметрами и без параметров, и добавьте его в словарь C # - PullRequest
0 голосов
/ 03 мая 2018

У меня есть словарь в коде, подобном этому:

Dictionary<string, Delegate> BODictionary= new Dictionary<string, Delegate>();

Я хочу добавить для словаря много типов подписей функций, но для объявления только одного универсального делегата я пытаюсь сделать этот код:

public class BOMock : BOBase
{
  //  private delegate int DelInt(int id);
  //  private delegate string DelString(string name);
    public delegate T Del<T>(T item);

    public int Id { get; set; }
    public string Name { get; set; }
    public BOMock() : base()
    {

    }
    public BOMock(int id, string name) : base()
    {
        Id = id;
        Name = name;
    }
    public override long Init(IModule module, ref Dictionary<string, Delegate> BODictionary)
    {
        try
        {

            base.Init(module, ref BODictionary);

            BODictionary.Add(this.GetType().Name + "." + nameof(getMockById), new Del<int>(getMockById));
            BODictionary.Add(this.GetType().Name + "." + nameof(getMockByName), new Del<string>(getMockByName));
            **BODictionary.Add(this.GetType().Name + "." + nameof(getAllMock), new Del<Action>(getAllMock)????);// is it possible?**
            BODictionary.Add(this.GetType().Name + "." + nameof(getAllMock), new Del<Action>(getAllMock1));// is it possible?
            BODictionary.Add(this.GetType().Name + "." + nameof(getAllMock), new Del<string>(getAllMock2));// is it possible?
            return 0;
        }
        catch (Exception ex)
        {

            return ex.HResult;
        }
    }

    private int getMockById(int Id)
    {
        return Id;
    }
    private string getMockByName(string name)
    {
        return name;
    }
    private void getAllMock()
    {

    }
    private void getAllMock1(string name)
    {

    }
    private string getAllMock2()
    {
        return "";
    }
}

как можно объявить один общий делегат, который также возвращает параметры и не возвращает, либо получает параметры, но не получает?

у кого-нибудь есть идеи?

спасибо

1 Ответ

0 голосов
/ 03 мая 2018

Ваш делегат объявлен как , ожидающий экземпляр T и , возвращающий единицу. Поэтому, если вы предоставляете экземпляр Action, вам необходимо вернуть и Action. Чтобы делегат вообще ничего не возвращал, используйте другой делегат:

delegate void SecondDel<T>(T item);

или просто Action<T> SecondDel, который является сокращением для первого.

Однако даже это не поможет вам, если вы поместите всех своих делегатов в один словарь, значение которого равно Delegate. Однако Delegate не является строго типизированным, поэтому следующее не будет работать:

var del = BODictionary("myString");
int i = del(1);
var another del = BODictionary("MyString2");
string anotherDel("Hello World");

потому что значения в словаре просто Delegate. Таким образом, даже если вы вставите Func<int> (что является еще одним сокращением для delegate T MyDel<T>()) в тот же словарь с Func<string>, вы не можете ожидать, что компилятор выведет правильный тип для ожидаемый ключ - это runtime-information . Словарь имеет ровно один единственный тип для всех своих значений, а не только один тип для первого значения и другой тип для второго.

Чтобы выполнить делегатов, вам нужно позвонить DynamicInvoke. Однако это просто перезапустит object, который вы должны привести к вашему фактическому типу:

var del = BODictionary("myString");
int i = (int) del.DynamicInvoke(1);
var another del = BODictionary("MyString2");
string str = (string) anotherDel.DynamicInvoke("Hello World");
...