C#:从基类静态方法确定派生对象类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/300181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: Determine derived object type from a base class static method
提问by Steve Hawkins
In a C# program, I have an abstract base class with a static "Create" method. The Create method is used to create an instance of the class and store it locally for later use. Since the base class is abstract, implementation objects will always derive from it.
在 C# 程序中,我有一个带有静态“Create”方法的抽象基类。Create 方法用于创建类的实例并将其存储在本地以备后用。由于基类是抽象的,实现对象总是从它派生出来的。
I want to be able to derive an object from the base class, call the static Create method (implemented once in the base class) through the derived class, and create an instance of the derived object.
我希望能够从基类派生一个对象,通过派生类调用静态Create方法(在基类中实现一次),并创建派生对象的实例。
Are there any facilities within the C# language that will allow me to pull this off. My current fallback position is to pass an instance of the derived class as one of the arguments to the Create function, i.e.:
C# 语言中是否有任何工具可以让我实现这一点。我当前的后备位置是将派生类的实例作为参数之一传递给 Create 函数,即:
objDerived.Create(new objDerived(), "Arg1", "Arg2");
采纳答案by chilltemp
Try using generics:
尝试使用泛型:
public static BaseClass Create<T>() where T : BaseClass, new()
{
T newVar = new T();
// Do something with newVar
return T;
}
Sample use:
样品用途:
DerivedClass d = BaseClass.Create<DerivedClass>();
回答by technophile
You can't do it without outside information; either the type of the derived class, an instance of it, or the fully-qualified name of the derived class. Any of these are equivalent to what you're already doing; there isn't a better solution I'm aware of. The very nature of static methods precludes anything more elegant.
没有外部信息,你做不到;派生类的类型、它的实例或派生类的完全限定名称。这些中的任何一个都等同于您已经在做的事情;我知道没有更好的解决方案。静态方法的本质排除了任何更优雅的方法。
回答by Joel Coehoorn
Sounds like you need to make the Create() method abstract. And once you do that you might as well rename it and make it the constructor as well. Then you can have a different Init() method that you call after the object is constructed if you need to, and normal polymorphism effects will handle things.
听起来您需要将 Create() 方法抽象化。一旦你这样做了,你也可以重命名它并使它成为构造函数。然后,如果需要,您可以在构造对象后调用不同的 Init() 方法,并且正常的多态效果将处理事情。
回答by Charles Bretana
You want to create a new instance of derived from inside another instance of derived, using a static factory method on the abstract base class? if so, I wonder Why... But ...
您想使用抽象基类上的静态工厂方法从另一个派生实例内部创建一个新的派生实例吗?如果是这样,我想知道为什么......但是......
public abstract class MyBase
{
public static T GetNewDerived<T>() where T : MyBase, new()
{
return new T();
}
}
public class DerivedA : MyBase
{
public static DerivedA GetNewDerived()
{
return GetNewDerived<DerivedA>();
}
}
public class DerivedB : MyBase
{
public static DerivedB GetNewDerived()
{
return GetNewDerived<DerivedB>();
}
}
Is this what you want ?
这是你想要的吗 ?
回答by Chris Marisic
I'm not sure what your design goals are but from what you asked it sounds like it might end up with alot of code smell. I think you should really look into the Inversion of Control(IoC) / Dependency Injection (DI) design patterns that are implemented in numerous frameworks such as Microsoft Unity, Castle Windsor, StructureMap, Ninject, Spring.Net and so forth.
我不确定您的设计目标是什么,但从您的要求来看,它听起来可能最终会产生很多代码异味。我认为您应该真正研究在 Microsoft Unity、Castle Windsor、StructureMap、Ninject、Spring.Net 等众多框架中实现的控制反转(IoC)/依赖注入(DI)设计模式。
I think if you look at using an IoC container it will solve your problem in a much cleaner and loosely coupled way.
我认为如果您考虑使用 IoC 容器,它将以更清洁和松散耦合的方式解决您的问题。
回答by Jeff Yates
Summary
概括
There are two main options. The nicer and newer one is to use generics, the other is to use reflection. I'm providing both in case you need to develop a solution that works prior to .NET 2.0.
有两个主要选项。更好和更新的一种是使用泛型,另一种是使用反射。如果您需要开发一个适用于 .NET 2.0 之前的解决方案,我会同时提供两者。
Generics
泛型
abstract class BaseClass
{
public static BaseClass Create<T>() where T : BaseClass, new()
{
return new T();
}
}
Where the usage would be:
用途在哪里:
DerivedClass derivedInstance = BaseClass.Create<DerivedClass>();
Reflection
反射
abstract class BaseClass
{
public static BaseClass Create(Type derivedType)
{
// Cast will throw at runtime if the created class
// doesn't derive from BaseClass.
return (BaseClass)Activator.CreateInstance(derivedType);
}
}
Where the usage would be (split over two lines for readability):
用法在哪里(分为两行以提高可读性):
DerivedClass derivedClass
= (DerivedClass)BaseClass.Create(typeof(DerivedClass));