How to add Func<T, string> of constrained Ts to a collection using that constrained type
I'm trying to create a list of Functions but I'm struggling. Here is a simplified version:
publ开发者_运维技巧ic 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?
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.
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);
}
}
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.
加载中,请稍侯......
精彩评论