Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.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# - Fatal编程技术网

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