How do I create a generic method with an optional generic type? This is what I have right now, which works
public GridViewColumn<T> Column<D>(String HeaderText, D decorator) where D: IColumnDecorator, new()
{
GridViewColumn<T> column = new GridViewColumn<T>();
column.HeaderText = HeaderText;
column.Decorator = new D();
return column;
}
As you can see, I need to instantiate the type D (implements IColumnDecorator) inside the Column() method.
The issue is, the type "D" is optional. If Null, I want to explicitly use a default ColumnDecorator that I have. something like
public GridViewColumn<T> Column<D>(String HeaderText, D decorator) where D: IColumnDecorator, new()
{
GridViewColumn<T> column = new GridViewColumn<T>();
column.HeaderText = HeaderText;
if(decorator ==null)
{
column.Decorator = new DefaultColumnDecorator();
}
else{
column.Decorator = new D();
}
return column;
}
Please help. Thanks!
[Edit].
Here is how I want to use it in razor MVC if I have a custom IColumnDecorator implementation
@Model.[IEnumerable].Grid(grid=>{
..
...
grid.columns(
grid.Column<MyOwnColumnDecorator>("FirstColumn")
)
});
If I don't have any and want to use default, then I want to be able to do something like
@Model.[IEnumerable].Grid(grid=>{
..
...
grid.columns(
grid.Column("FirstColumn",null) or simply grid.Column("FirstColumn");
)
});
In your current code, you don't need the decorator
parameter since you create a new instance of D
and use that instead.
public GridViewColumn<T> Column<D>(String HeaderText) where D: IColumnDecorator, new()
{
GridViewColumn<T> column = new GridViewColumn<T>();
column.HeaderText = HeaderText;
column.Decorator = new D();
return column;
}
If you have a default parameter type to use, you don't need to use generics:
public GridViewColumn<DefaultColumnDecorator> Column(String headerText)
{
return Column<DefaultColumnDecorator>(headerText);
}
Alternatively you could keep the parameter and remove the new()
constraint:
public GridViewColumn<T> Column<D>(String HeaderText, D decorator) where D : IColumnDecorator
{
GridViewColumn<T> column = new GridViewColumn<T>();
column.HeaderText = HeaderText;
column.Decorator = decorator;
return column;
}
public GridViewColumn<DefaultColumnDecorator> Column(String headerText)
{
return Column(headerText, new DefaultColumnDecorator());
}
Use a default parameter:
public GridViewColumn<T> Column<D,T>(string HeaderText, D decorator = null)
where D : IColumnDecorator, class, new()
You shouldn't be instantiating type D
from the Column
method. Instead, you should let the caller pass it in.
public GridViewColumn<T> Column(String HeaderText, IColumnDecorator decorator)
{
GridViewColumn<T> column = new GridViewColumn<T>();
column.HeaderText = HeaderText;
if(decorator ==null)
{
column.Decorator = new DefaultColumnDecorator();
}
else{
column.Decorator = decorator;
}
return column;
}
The rationale is here: http://en.wikipedia.org/wiki/Dependency_injection
After playing with some options I made a sample that works with the following code:
public GridViewColumn<TResult> Column<TColumn>(string HeaderText, TColumn decorator = null) where TColumn : class, IColumnDecorator
{
GridViewColumn<TResult> column = new GridViewColumn<TResult>();
column.HeaderText = HeaderText;
if(decorator == null)
{
column.Decorator = new DefaultColumnDecorator();
}
else
{
column.Decorator = decorator;
}
return column;
}
In order to make this work you need to consider the following:
In my sample I was able to call this method in the following two ways with the same result:
@Model.[IEnumerable].Grid(grid=>{
..
...
grid.columns(
grid.Column<MyOwnColumnDecorator>("FirstColumn",null);
)
});
@Model.[IEnumerable].Grid(grid=>{
..
...
grid.columns(
grid.Column<MyOwnColumnDecorator>("FirstColumn");
)
});
Good luck!
There's a lot of ways to do what you're trying to do, how about asking the caller to pass a way to make a decorator?
public GridViewColumn<T> Column(string HeaderText, Func<IColumnDecorator> decoratorGenerator)
{
GridViewColumn<T> column = new GridViewColumn<T>();
column.HeaderText = HeaderText;
column.Decorator = decoratorGenerator != null ? decoratorGenerator()
: new DefaultColumnDecorator() ;
return column;
}
I see two things you are missing. One is a default parameter setting decorator = null
and the other is the use of default(T)
. I have rewrote yours as follows but I can't test it obviously - should be close though.
public GridViewColumn<TResult> Column<TColumn>(string HeaderText, TColumn decorator = null) where TColumn : IColumnDecorator, new()
{
GridViewColumn<TResult> column = new GridViewColumn<TResult>();
column.HeaderText = HeaderText;
column.Decorator = decorator == null ? new DefaultColumnDecorator() : default(TColumn);
return column;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.