C# 如何在静态基方法中创建继承的实例?
从一个例子来看,我可能会这样做C# 如何在静态基方法中创建继承的实例?,c#,C#,从一个例子来看,我可能会这样做 var obj= Activator.CreateInstance(GetType()); 但不确定如何在静态基方法中获取继承类的typeof 这是前进的最佳途径吗 public static Method<T>() where T : SomeBase, new() publicstaticmethod(),其中T:SomeBase,new() 也许您最好尝试使用抽象工厂模式? 您可以将基类设置为泛型,并在派生类中关闭泛型 public ab
var obj= Activator.CreateInstance(GetType());
但不确定如何在静态基方法中获取继承类的typeof
这是前进的最佳途径吗
public static Method<T>() where T : SomeBase, new()
publicstaticmethod(),其中T:SomeBase,new()
也许您最好尝试使用抽象工厂模式?
您可以将基类设置为泛型,并在派生类中关闭泛型
public abstract class CreatorOf<T> where T : CreatorOf<T>
{
public static T Create()
{
return (T)Activator.CreateInstance(typeof(T));
}
}
public class Inheritor : CreatorOf<Inheritor>
{
public Inheritor()
{
}
}
public class Client
{
public Client()
{
var obj = Inheritor.Create();
}
}
公共抽象类CreatorOf,其中T:CreatorOf
{
publicstatict-Create()
{
return(T)Activator.CreateInstance(typeof(T));
}
}
公共类继承者:创建者
{
公共继承人()
{
}
}
公共类客户端
{
公共客户机()
{
var obj=Inheritor.Create();
}
}
有些人认为这是一个问题,但我相信有些情况是可以接受的。 < P>没有一个派生的静态方法。因此,无法创建一个静态工厂方法,该方法根据调用它的派生类返回不同的类型 正如Lonli Lokli所建议的,您应该使用 抽象工厂与静态工厂方法的优点:
- 它更加灵活,允许为抽象工厂的每个实现者提供工厂逻辑的新实现(可以是您想要的复杂程度)。如果需要,每个类可以有多个工厂
- 因为您没有调用静态方法,所以在运行时替换它要容易得多。这对于在单元测试中注入模拟非常有用
- 抽象工厂的用户必须具有工厂实例才能创建派生类型
- 您必须为每个派生类编写一个新的抽象工厂实现
MyClass myClass = new MyClassFactory().Create();
至于工厂实现中的代码复制:为实现者节省一点点输入是毫无意义的。编程的目标是编写可以阅读、理解和轻松修改的代码。没有任何编程目标可以节省纸张或按键:)可能。但我想用一种自我发现的方式来做。static Method()似乎与抽象工厂几乎是同一回事,而不是拥有抽象工厂。谢谢你指出这一点。让我思考。@sgtz最近有一个关于C#抽象工厂的问题,我给出了一个可能有用的答案,这就是答案。我不确定它是否在Cා中工作。如果它确实有效(谷歌有文章说不会,但是),那么它不是你认为的反模式,如果抽象工厂对OP来说不够吸引人,那么它可能是一个解决方案:@默林摩根·格雷厄姆说得清楚,我认为这不是一种“反模式”(一个词被频繁地贴在IMHO上)。我只是想提醒OP注意其他意见,以便他们自己决定是否适合自己的情况。它在C#BTW.+1 BTW中运行良好。我认为您链接的问题与此模式不匹配,因为在他们的示例中,泛型参数与派生类型不同。在您的例子中,它是相同的,因此是CRTP。@MerlynMorgan Graham是的,可能是的,尽管一些海报似乎在原则上反对关闭泛型基类的派生类。但是,这不是我的观点,所以我很难说TBH。我不会使用通用接口来实现抽象工厂,因为工厂及其产品都是抽象的,所以类型参数化没有用处。如果工厂的客户机只依赖于非通用的IFactory和IProduct抽象,那么它将与这两种抽象的具体类型完全解耦。使它们成为泛型要么强制客户机是泛型的,要么必须关闭类型,这会破坏抽象。想想DoSomething(IfaCuttoFor)和DoSomething(iFaCut厂房)。史提夫:我只是在最后一分钟就把它扔进去了,没有好好思考。现在我想了想,我并不是这样创建抽象工厂的。当我这样做的时候似乎有点奇怪:)修复…是的,因为泛型工厂接口中的类型参数只会显示为返回类型,那么您可以使用协方差来传递,比如,一个IFactory到一个需要IFactory的方法,但我认为你不会从通用接口中得到任何好处,所以我仍然认为你的最终版本更好。:)@史蒂夫:是的。我想不出有什么有趣的场景可以通用地使用
IFactory
。它给您带来的好处是,您只需定义一次工厂接口。但是错误的灵活性(不能在基类中以灵活的方式使用它)使得用户很难理解使用工厂的正确方法(正如我的第一次修订版所证明的)。每次重写界面都要安全得多,而且打字成本也很低——这与我在回答中推荐的使用抽象工厂的方法相同。
MyClass myClass = new MyClassFactory().Create();