C# 具有可选泛型参数的泛型方法

C# 具有可选泛型参数的泛型方法,c#,generics,C#,Generics,如何创建具有可选泛型类型的泛型方法?这就是我现在拥有的,有效的 public GridViewColumn<T> Column<D>(String HeaderText, D decorator) where D: IColumnDecorator, new() { GridViewColumn<T> column = new GridViewColumn<T>(); column.

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

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

使用默认参数:

public GridViewColumn<T> Column<D,T>(string HeaderText, D decorator = null)
    where D : IColumnDecorator, class, new()
公共GridViewColumn(字符串HeaderText,D decorator=null) 其中D:IColumnDecorator,类,new()
在当前代码中,您不需要
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;
}

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

 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;
        }
publicGridViewColumn列(字符串HeaderText、IColumnDecorator decorator)
{
GridViewColumn=新的GridViewColumn();
column.HeaderText=HeaderText;
if(decorator==null)
{
column.Decorator=新的DefaultColumnDecorator();
}
否则{
column.Decorator=Decorator;
}
返回列;
}

基本原理如下:

我发现您缺少两件事。一个是默认参数设置
decorator=null
,另一个是使用。我已经重写了你的如下,但我不能测试它显然-应该是接近虽然

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;
}
公共GridViewColumn列(字符串HeaderText,TColumn decorator=null),其中TColumn:icolumndcorator,new() { GridViewColumn=新的GridViewColumn(); column.HeaderText=HeaderText; column.Decorator=Decorator==null?新建DefaultColumnDecorator():默认值(TColumn); 返回列; }
在玩了一些选项后,我制作了一个示例,可以使用以下代码:

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;
}
publicGridViewColumn列(字符串HeaderText,TColumn decorator=null),其中TColumn:class,icolumndcorator
{
GridViewColumn=新的GridViewColumn();
column.HeaderText=HeaderText;
if(decorator==null)
{
column.Decorator=新的DefaultColumnDecorator();
}
其他的
{
column.Decorator=Decorator;
}     
返回列;
}
为了进行这项工作,你需要考虑以下内容:

  • 您需要添加类限制,以便能够将参数定义为null
  • 您不应该使用default(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");
      )
});
@Model.[IEnumerable].Grid(Grid=>{
..
...
网格列(
grid.Column(“FirstColumn”,null);
)
});
@模型。[IEnumerable]。网格(网格=>{
..
...
网格列(
网格栏(“第一栏”);
)
});

祝你好运

有很多方法可以做你想做的事情,让打电话的人给你一个做装饰师的方法怎么样

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;
}
publicGridViewColumn列(字符串HeaderText,Func decoratorGenerator)
{
GridViewColumn=新的GridViewColumn();
column.HeaderText=HeaderText;
column.Decorator=decoratorGenerator!=null?decoratorGenerator()
:新建DefaultColumnDecorator();
返回列;
}

为什么第一个方法让调用方在
D
的实例中传递?您从未使用过它。为什么需要在
列()中实例化类型
D
?让调用方在实例中通过会更灵活。Justin,你是什么意思?Yuxiu,我这样做是因为我不希望我的调用者在调用时必须指定具体类型的“new”关键字。如果你想要一个默认的ColumnDecorator,只需重载即可。有一个非泛型重载-使用columndecorator。为泛型提供(非null)默认值是没有意义的。。。。这更符合接口参数。你不能那样使用它。在这个调用中,您正在硬编码decorator的类型,当您尝试实例化DefaultDecorator时,您的代码将无法编译,因为您的方法需要一种类型的MyOwnColumnDecorator。我不知道我是否解释了自己。谢谢ShadowCat7,现在,我该如何调用该方法?仅提供空值作为第二个参数?默认参数允许您不必添加第二个参数。您可以只提供字符串和类型参数来调用它。新的D()最好写为默认值(D),我喜欢您建议的解决方案的其余部分。@phillip-
new D()
default(D)
完全不同-
default(D)
如果
D
是类类型,则
default(D)
为null,在没有new()约束的第三个代码块中,该方法根本不需要是泛型的。谢谢Lee。在尝试了所有的解决方案之后,看起来这是最好的方法。只需重载column方法。如果您有一个实现,请使用它。否则,使用默认值。谢谢!philip,如果我希望decorator是可选的或空的,我该如何调用此代码?我试图指定…Column(“Header Text”,null),它表示尝试显式指定用法。Column(“HeaderText”)是您所要做的全部,因为第二个参数已经指定。您应该用类似
Column.Decorator=Decorator??新的DefaultColumnDecorator()
因为如果调用方提供了
装饰程序,则当前正在分配null(如果D是类类型)。Key Phillip,我尝试过这样做。。。grid.column(“HeaderText”),但得到一个错误。但如果我提供了一个具体的类型,那么我就像grid.Column(“FirstColumn”)一样。顺便说一句,我必须在约束中添加一个“类”,否则,它不会允许
 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;
        }
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;
}
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;
}
@Model.[IEnumerable].Grid(grid=>{
      ..
      ...
      grid.columns(
         grid.Column<MyOwnColumnDecorator>("FirstColumn",null);
      )
});

@Model.[IEnumerable].Grid(grid=>{
      ..
      ...
      grid.columns(
         grid.Column<MyOwnColumnDecorator>("FirstColumn");
      )
});
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;
}