Как добавить Funcограниченного Ts в коллекцию, используя этот тип ограничения - PullRequest
1 голос
/ 21 января 2011

Я пытаюсь создать список функций, но я изо всех сил. Вот упрощенная версия:

public class ValueGetter
{
    public List<Func<Control, string>> Operations { get; set; }

    public ValueGetter()
    {
        this.Operations = new List<Func<Control, string>>();
    }

    public void Map<T>(Func<T, string> valueGetter) where T : Control
    {
        this.Operations.Add(valueGetter);
    }        
}

Проблема возникает, когда я пытаюсь добавить функцию в коллекцию. Я бы через это смог сделать, так как T это элемент управления, но он не компилируется.

Есть ли способ добавить функцию в эту коллекцию?

Ответы [ 3 ]

1 голос
/ 21 января 2011

Вы должны объявить класс как общий:

public class ValueGetter<T> where T : Control
{
    public List<Func<T, string>> Operations { get; set; }

    public ValueGetter()
    {
        this.Operations = new List<Func<T, string>>();
    }

    public void Map(Func<T, string> valueGetter)
    {
        this.Operations.Add(valueGetter);
    }        
}
1 голос
/ 21 января 2011

Это не сработает, потому что у вас, например, будет Func<Button, string> в вашем списке, но вы можете в итоге назвать его, скажем, Label. Какова функция, которая ожидает Button, ожидается, что делать с Label?

Вы могли бы сделать что-то вроде этого:

public class ValueGetter<T> where T : Control
{
    public List<Func<T, string>> Operations { get; set; }

    public ValueGetter()
    {
        this.Operations = new List<Func<T, string>>();
    }

    public void Map(Func<T, string> valueGetter)
    {
        this.Operations.Add(valueGetter);
    }
}

Другими словами, иметь отдельные ValueGetter s для каждого типа элемента управления.

Редактировать: Другая идея: Вы можете добавить функцию, которая просто разрешает операцию, только если тип является правильным, например:

public void Map<T>(Func<T, string> valueGetter) where T : Control
{
    this.Operations.Add(control => (control is T) ? valueGetter((T) control) : null);
}

В этом случае, если ожидающей функции Button будет дан Label, она просто вернет ноль.

1 голос
/ 21 января 2011

Это невозможно.

Хотя T является Control, не все Control с T с.
Что произойдет, если вы добавите Func<TextBox, bool> в список, затем назовите его (как Func<Control, string>) с Button?

Вы можете использовать ковариацию , чтобы привести Func<Control, string> к Func<T, string> where T : Control>, потому что любой возможный T также Control.

...