如何添加Func使用该约束类型将受约束的 T 存储到集合中

发布于 2024-10-13 03:08:45 字数 512 浏览 4 评论 0原文

我正在尝试创建一个函数列表,但我很挣扎。这是一个简化版本:

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 是一个控件,但这无法编译。

有什么方法可以将函数添加到这个集合中吗?

I'm trying to create a list of Functions but I'm struggling. Here is a simplified version:

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);
    }        
}

The issue comes when I try to add the function to the collection. I would have through I'd be able to do this as T is a control however this doesn't compile.

Is there a way I can add the function to this collection?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

戏剧牡丹亭 2024-10-20 03:08:45

那是不可能的。

虽然 T 是一个 Control,但并非所有 Control 都是 T
如果将 Func 添加到列表中,然后使用 Button< 调用它(作为 Func),会发生什么情况/代码>?

您可以使用协方差来转换Func;Func;其中 T : Control>,因为任何可能的 T 也是 Control

That's not possible.

Although T is a Control, not all Controls are Ts.
What happens if you add a Func<TextBox, bool> to the list, then call it (as a Func<Control, string>) with a Button?

You can use covariance to cast a Func<Control, string> to a Func<T, string> where T : Control>, because any possible T is also a Control.

不再让梦枯萎 2024-10-20 03:08:45

您应该将该类声明为通用类:

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);
    }        
}

You shoud declare the class as generic:

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);
    }        
}
感性不性感 2024-10-20 03:08:45

这是行不通的,因为您最终会在列表中包含一个 Func ,但您最终可能会使用一个 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);
    }
}

换句话说,为每个 Control 类型设置单独的 ValueGetter

编辑:另一个想法:您可以添加一个仅在类型正确时才允许操作的函数,例如:

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

在这种情况下,如果 Button 期望函数是给定一个Label,它只会返回 null。

This wouldn’t work, because you would end up having, for example, a Func<Button, string> in your list, but you could end up calling it with, say, a Label. What is the function, which expects a Button, expected to do with a Label?

You could do something like this:

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);
    }
}

In other words, have separate ValueGetters for each Control type.

Edit: Another idea: You could add a function that simply allows the operation only if the type is right, for example:

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

In this case, if the Button-expecting function is given a Label, it would simply return null.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文