这可能是一个愚蠢的问题,但我正在开发一个组件,我有一个类,其属性如下
public class Grid()
{
..
public IDecorator Decorator { get; set;}
}
我想要的是让用户以下列方式指定自己的实现IDecorator的自定义类
...BuildGrid(
grid=>{
..
grid.Decorator = [CustomNameSpace].[DecoratorClass]
//as in
grid.Decorator = Com.MyCompany.DivDecorator
..
});
Com.MyCompany.DivDecorator实现了IDecorator接口。那么如果没有最终用户在
中指定“new”关键字,我应该怎么做呢grid.Decorator = new Com.MyCompany.DivDecorator();
我知道我在这里错过了一些关键的c#概念。
由于
[编辑]
我试图做像这里的Java DisplayTag库那样的事情
http://www.displaytag.org/1.2/tut_decorators.html
他们这样做的方式是
... decorator="org.displaytag.sample.Wrapper"
所以我想而不是
public IDecorator Decorator { get; set;}
我应该做
public String Decorator (get; set;}
然后在内部使用TypeOf()来解决它....只是想知道是否有任何其他方式优雅地在C#中执行它。
由于
答案 0 :(得分:8)
您可以使用工厂方法:
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 => ... );
答案 1 :(得分:5)
如果我理解你在寻找什么,你可以使用通用:
public class Grid<TDecorator> where TDecorator : IDecorator, new() {
private readonly TDecorator _decorator;
public Grid() {
_decorator = new TDecorator();
}
public TDecorator Decorator { get { return _decorator; } }
}
他们通过调用得到一个网格:
var myGrid = new Grid<MyDecorator>();
答案 2 :(得分:3)
您可以使BuildGrid通用,并指定new()约束。
e.g。 BuildGrid<T>() where T : IDecorator, new()
虽然我并不是100%明白你想要的东西。
答案 3 :(得分:1)
鉴于您有一个界面,您将在某处创建一个实例。 您可以注入它(请参阅IOC模式或实例工厂模式)
有各种各样的场景。 但要理解factory patterns will help
1)该类在程序集内部。 发现类型 Getting all types that implement an interface 并创建一个实例 http://msdn.microsoft.com/en-us/library/wccyzw83.aspx
2)代码是外部的, http://msdn.microsoft.com/en-us/library/dd460648.aspx
3)或文件 http://msdn.microsoft.com/en-us/library/system.reflection.assembly.load%28v=vs.110%29.aspx
答案 4 :(得分:0)
感谢所有帮助过我的人!我决定使用p.s.w.g的Activator.CreateInstance方法。原因是,对于Grid Component,我有一个表级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])
)
})
所以考虑到我的情况,因为每个列都有可能有自己的装饰器类。所以我将不得不使用Activator.CreateInstance。
再次感谢大家的帮助!!再次非常感谢你的时间!!
[编辑]。在阅读p.s.w.g的最后两条评论之后,可以采用泛型方法!