I have the following code:
public interface IMenuItem
{
IWebElement Parent { get; }
}
public class MenuItems
{
public T GetMenuItem<T>() where T : IMenuItem, new()
{
var menuItem = new T();
return menuItem;
}
}
public abstract class Page : IEnumerable<IComponent>
{
private Func<IMenuItem> _getMenuItems = new MenuItems().GetMenuItem<IMenuItem>;
}
I'm trying to store the new MenuItems().GetMenuItem<IMenuItem>
function in _getMenuItems
field, but since this is a generic function this isn't working. How can I store generic functions into a variable?
Doing new MenuItems().GetMenuItem<IMenuItem>
won't work and it tells me:
'IMenuItem' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'MenuItems.GetMenuItem()'
Now I have many concrete types that implement IMenuItem
I want the delegate to accept those. I don't want to make a seperate delegate for every concrete type that implements IMenuItem
. Rather I have a single delegate that can accept concrete types that implement IMenuItem
.
Generic Methods All generic method declarations have a type parameter section delimited by angle brackets (< and >) that precedes the method's return type ( < E > in the next example). Each type parameter section contains one or more type parameters separated by commas.
Generics are syntax components of a programming language that can be reused for different types of objects. Typically, generics take the form classes or functions, which take type(s) as a parameter. Generics are also commonly referred to as templates , and in C++ are officially called templates.
You can also define generic functions that take variable numbers of arguments in just the same way as ordinary functions. For example: (defgeneric foo (a . b)) defines a generic function (with no methods) taking at least one argument, with the second always being of class <list>.
The problem is with the new() constraint.
The new constraint specifies that a type argument in a generic class declaration must have a public parameterless constructor. To use the new constraint, the type cannot be abstract.
Since IMenuItem
is an interface, it cannot be instantiated, and therefore the new() constraint will be a problem.
Edit:
You can solve this in a couple of ways:
You can use reflection for retrieving the method and invoking it:
var method = typeof(MenuItems).GetMethod("GetMenuItem");
var instance = new MenuItems(); // Maybe convert the class into a static class??
var genericMethod = method.MakeGenericMethod(typeof(MenuItem1));
var result = genericMethod.Invoke(instance, null) as IMenuItem;
Use dynamic to invoke it:
dynamic instance = new MenuItems(); // Maybe convert the class into a static class??
var result = instance.GetMenuItem<MenuItem1>() as IMenuItem;
Hold an instance of MenuItems instead of the method itself:
var menuItems = new MenuItems();
var result = _instance.GetMenuItem<MenuItem1>() as IMenuItem;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With