带有可选通用参数的通用方法

时间:2013-08-02 20:06:21

标签: c# generics

如何使用可选的泛型类型创建泛型方法?这就是我现在所拥有的,有效的

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

如您所见,我需要在Column()方法中实例化类型D(实现IColumnDecorator)。

问题是,“D”类型是可选的。如果是Null,我想明确使用我拥有的默认ColumnDecorator。

之类的东西
 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;
        }

请帮忙。谢谢!

[编辑]。

如果我有自定义的IColumnDecorator实现,我想在razor MVC中使用它

@Model.[IEnumerable].Grid(grid=>{
      ..
      ...
      grid.columns(
         grid.Column<MyOwnColumnDecorator>("FirstColumn")
      )
});

如果我没有,并且想要使用默认值,那么我希望能够做类似

的事情
@Model.[IEnumerable].Grid(grid=>{
          ..
          ...
          grid.columns(
             grid.Column("FirstColumn",null) or simply grid.Column("FirstColumn"); 
          )
    });

6 个答案:

答案 0 :(得分:6)

在您当前的代码中,您不需要decorator参数,因为您创建了D的新实例并使用了该实例。

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

如果您要使用默认参数类型,则无需使用泛型:

public GridViewColumn<DefaultColumnDecorator> Column(String headerText)
{
    return Column<DefaultColumnDecorator>(headerText);
}

或者,您可以保留参数并删除new()约束:

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

答案 1 :(得分:1)

使用默认参数:

public GridViewColumn<T> Column<D,T>(string HeaderText, D decorator = null)
    where D : IColumnDecorator, class, new()

答案 2 :(得分:1)

您不应该从D方法实例化类型Column。相反,你应该让调用者传入它。

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

理由如下:http://en.wikipedia.org/wiki/Dependency_injection

答案 3 :(得分:0)

在玩了一些选项之后,我制作了一个使用以下代码的示例:

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

为了完成这项工作,您需要考虑以下事项:

  • 您需要添加类限制才能将参数定义为null。
  • 您不应使用默认(TColumn),因为它会因类限制而返回null。
  • 由于某种原因,如果您使用“?:”语法,编译器不接受您实例化DefaultColumnDecorator类型,但如果您使用常规if语句,它将起作用。
  • 似乎新的()限制对此无效。

在我的示例中,我能够通过以下两种方式调用此方法,结果相同:

@Model.[IEnumerable].Grid(grid=>{
      ..
      ...
      grid.columns(
         grid.Column<MyOwnColumnDecorator>("FirstColumn",null);
      )
});

@Model.[IEnumerable].Grid(grid=>{
      ..
      ...
      grid.columns(
         grid.Column<MyOwnColumnDecorator>("FirstColumn");
      )
});
祝你好运!

答案 4 :(得分:0)

有很多方法可以做你正在尝试做的事情,请求调用者传递一种方法来制作装饰器怎么样?

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

答案 5 :(得分:-1)

我看到你遗失的两件事。一个是默认参数设置decorator = null,另一个是default(T)的使用。我已经重写了你的内容如下,但我无法测试它 - 尽管应该接近。

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