Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在不使用“启动”的情况下启动一个类;新";关键词?_C#_Asp.net Mvc 4_Razor - Fatal编程技术网

C# 如何在不使用“启动”的情况下启动一个类;新";关键词?

C# 如何在不使用“启动”的情况下启动一个类;新";关键词?,c#,asp.net-mvc-4,razor,C#,Asp.net Mvc 4,Razor,这可能是一个愚蠢的问题,但我正在开发一个组件,我有一个具有如下属性的类 public class Grid() { .. public IDecorator Decorator { get; set;} } 我想要的是用户指定自己的自定义类,该类通过以下方式实现IDecorator ...BuildGrid( grid=>{ .. grid.Decorator = [CustomNameSpace].[DecoratorClass] //as in grid.Decorato

这可能是一个愚蠢的问题,但我正在开发一个组件,我有一个具有如下属性的类

public class Grid()
{
 ..
 public IDecorator Decorator { get; set;}

}
我想要的是用户指定自己的自定义类,该类通过以下方式实现IDecorator

...BuildGrid(
grid=>{
..
grid.Decorator =  [CustomNameSpace].[DecoratorClass] 
//as in 
grid.Decorator =  Com.MyCompany.DivDecorator
..
});
DivDecorator实现IDecorator接口。那么,如果最终用户没有像中那样指定“new”关键字,我该如何做呢

grid.Decorator = new Com.MyCompany.DivDecorator();
我知道我遗漏了一些关键的c#概念

谢谢

[编辑]

我试图做一些类似于位于此处的Java DisplayTag库的事情

他们这样做的方式是

decorator=“org.displaytag.sample.Wrapper”

所以我想不是

public IDecorator Decorator { get; set;}
我应该这样做

public String Decorator (get; set;}
然后在内部使用TypeOf()来解析它。。。。只是想知道是否还有其他方法可以在C#中优雅地完成它


谢谢

您可以使用工厂方法:

public class DivDecorator
{
    public static IDecorator Create()
    {
        return new Com.MyCompany.DivDecorator()
    }
}

...

grid.Decorator = Com.MyCompany.DivDecorator.Create();
或单身人士:

public class DivDecorator
{
    public static readonly IDecorator Instance = new DivDecorator();
}

...

grid.Decorator = Com.MyCompany.DivDecorator.Instance;
在这两种情况下,您只需将
new
操作符移动到另一个位置

或者,您可以让用户指定类型,然后您需要在需要时进行实例化:

public class Grid
{
    public Type DecoratorType { get; set; }

    private IDecorator CreateDecorator()
    {
        return (IDecorator)Activator.CreateInstance(this.DecoratorType);
    }
}

...

grid.Decorator = typeof(Com.MyCompany.DivDecorator);
或者更好地使用泛型:

public class Grid<T> where T : IDecorator, new
{
    private T CreateDecorator()
    {
        return new T();
    }
}

BuildGrid<Com.MyCompany.DivDecorator>(grid => ... );
公共类网格,其中T:IDecorator,新
{
私有T CreateDecorator()
{
返回新的T();
}
}
构建网格(网格=>…);

您可以将BuildGrid设置为通用,并指定一个新的()约束

e、 g.
BuildGrid(),其中T:IDecorator,new()


虽然我不是100%清楚你想要什么。

如果我了解你想要什么,你可以使用通用的:

public class Grid<TDecorator> where TDecorator : IDecorator, new() {

    private readonly TDecorator _decorator;

    public Grid() {
        _decorator = new TDecorator();
    }

    public TDecorator Decorator { get { return _decorator; } }
}
公共类网格,其中TDecorator:IDecorator,new(){
专用只读TDecorator\u decorator;
公共电网(){
_装饰器=新的TDecorator();
}
公共TDecorator Decorator{get{return\u Decorator;}
}
他们会通过调用以下命令获得网格:

var myGrid = new Grid<MyDecorator>();
var myGrid=new Grid();

如果您有一个接口,您将在某处创建一个实例。 您可以注入它(请参见IOC模式或实例工厂模式)

有各种各样的情况。 但是理解

1) 该类位于程序集中。 发现类型 并创建一个实例

2) 代码是外部的,

3) 还是一个文件
感谢所有帮助我的人!我决定使用p.s.w.g的Activator.CreateInstance方法。原因是,对于网格组件,我有一个表级的Decorator,然后网格的每个列也可以有自己的Decorator。如

@Model.[MyIEnumberable].BuildGrid<Product>(grid=>{
grid.ShowHeader = false;
grid.CellSpacing = 0;
grid.CellPadding = 0;
grid.Decorator = "Com.MyCompany.DivDecorator";
grid.columns(
        grid.column(HeaderText: "First Column", Decorator:"Com.MyCompany.FirstColumnDecorator"...),
        grid.column(HeaderText: "Second Column", Decorator:"Com.MyCompany.SecondColumnDecorator"..),
        grid.column(HeaderText: "ThirdColumn", Text:@item.ProductID),
        grid.column(HeaderText: "ThirdColumn", Text:@item.[A Property only exist in grid.Decorator, achieved using dynamic/DynamicObject])
)
})
@Model.[MyIEnumberable].BuildGrid(grid=>{
grid.ShowHeader=false;
grid.CellSpacing=0;
grid.CellPadding=0;
grid.Decorator=“Com.MyCompany.DivDecorator”;
网格列(
grid.column(HeaderText:“First column”,Decorator:“Com.MyCompany.firstcolumndcorator”…),
grid.column(HeaderText:“第二列”,Decorator:“Com.MyCompany.secondColumndcorator”。),
grid.column(标题文本:“第三列”,文本:@item.ProductID),
grid.column(HeaderText:“ThirdColumn”,Text:@item。[属性仅存在于grid.Decorator中,使用dynamic/DynamicObject实现])
)
})
鉴于我的情况,由于每个列都可能有自己的decorator类,所以我必须使用Activator.CreateInstance

再次感谢大家的帮助!!再次感谢您的时间


[编辑]。在阅读了p.s.w.g的最后两条评论之后,泛型方法是一条出路

听起来你想让他们指定一个类型而不是一个实例,然后你的内部网格代码会自动更新一个实例并使用它。。大概是这样吧?您能解释一下用法吗?因此,当您将Decorator设置为实现IDecorator的某个类时,您希望能够访问IDecorator接口中未指定的其他方法/属性吗?
grid.Decorator=Com.MyCompany.DivDecorator
语法无效,请注意。你是说
grid.Decorator=typeof(…)
?听起来你真正想要的是依赖注入。你甚至可以通过为特定的接口预先注册来消除传递类型。基本上,我在看这个名为DisplayTag的Java组件,我非常喜欢他们的方式。也许就像Charleh和Tim所说的,我试图指定一个类型。所以在本例中,我应该指定一个表示类的“字符串”,然后使用typeOf()返回“接口”类?还有RedLou,我想要的是访问接口中的所有方法/属性,但要让最终用户像Java DisplayTag一样轻松。谢谢p.s.w.g。我想我最喜欢你的.CreateInstance方法。虽然不确定使用反射是否是一件好事,但它似乎是最干净的方式。非常感谢您向我展示了解决此问题的不同方法!我也喜欢泛型方法,不过,我在整个代码中有不同的装饰器,IDecorator、IRowDecorator、icolumndcorator等等。使用泛型版本而不是反射。正如所写的,它们都需要一个无参数构造函数,但如果不存在,则泛型版本将在编译时捕获它。@Liming每种方法都有优点和缺点。我更喜欢泛型方法,但对于泛型类,您必须将每个装饰器类型指定为不同的泛型参数。您还可以使用其他一些技巧,例如,在仔细考虑之后,使用一个通用方法,如
usedecotor()
@p.s.w.g。我想我开始更喜欢通用方法了。我假设我的组件的最终用户能够像grid.UseDecorator()这样做,然后,签名看起来像IDcorator UseDecorator(){return new T();},对吗?@Liming是的。如果您执行了类似于
Grid UseDecorator(){this.decorator=new T();return this;}
,您可以创建一种