Kri*_*rma 3 c# instance derived-class
典型情况如下.
class ServiceBase
{
public virtual InstanceBase GetObject() { return null; }
}
class ServiceA : ServiceBase
{
public override InstanceBase GetObject()
{
var v = new InstanceA();
v.Method();
return v;
}
}
class ServiceB : ServiceBase
{
public override InstanceBase GetObject()
{
var v = new InstanceB();
v.Method();
return v;
}
}
class InstanceBase
{
public virtual void Method() { }
}
class InstanceA : InstanceBase
{
public override void Method(){}
}
class InstanceB : InstanceBase
{
public override void Method() { }
}
Run Code Online (Sandbox Code Playgroud)
不同的服务处理不同的实例类.但是GetObject的代码对于所有服务都是类似的.我想通过扩展基类的执行最多的GetObject方法来减少代码库.
class ServiceBase
{
public virtual InstanceBase GetObject<T>()
{
var v= (InstanceBase)Activator.CreateInstance(typeof(T), new object[] { });
v.Method();
return v;
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎是一种实现方式.但是我不太担心使用反射,因为它可能会遇到性能问题.有没有更好的方法来实现这一目标?
是的,有两种方法:
1)通用方法:
class ServiceBase<T> where T : InstanceBase, new()
{
public InstanceBase GetObject() //you can make the return type even 'T'
{
var v = new T();
v.Method();
return v;
}
}
class ServiceA : ServiceBase<InstanceA>
{
}
class ServiceB : ServiceBase<InstanceB>
{
}
Run Code Online (Sandbox Code Playgroud)
这只是更好,因为它具有最少的代码重复,但我不确定通用性是否会成为一个麻烦.
2)如果不适合,你可以要求基类提供自己的InstanceBase.这看起来更简洁.喜欢:
abstract class ServiceBase
{
public abstract InstanceBase Instance { get; }
public InstanceBase GetObject() //you can make the return type even 'T'
{
Instance.Method();
return Instance;
}
}
class ServiceA : ServiceBase
{
public override InstanceBase Instance { get; } //return new InstanceA() here
}
class ServiceB : ServiceBase
{
public override InstanceBase Instance { get; } //return new InstanceB() here
}
Run Code Online (Sandbox Code Playgroud)
现在,从重写的属性Instance返回一个新实例InstanceBase或已经实例化的实例.这取决于你的逻辑,但是从所显示的方法来看,你每次都必须返回一个新实例.
哪个适合你取决于你的背景.无论是什么,请考虑:
1)这种方法很糟糕.
public virtual InstanceBase GetObject<T>()
{
var v= (InstanceBase)Activator.CreateInstance(typeof(T), new object[] { });
v.Method();
return v;
}
Run Code Online (Sandbox Code Playgroud)
首先,你必须在调用函数时指定类型参数,其中两个,每个人都有可能搞砸了.
ServiceA a = new ServiceA();
a.GetObject<InstanceB>(); // not probably what you want.
Run Code Online (Sandbox Code Playgroud)
2)在任何情况下,如果你想要它,你可以new()为泛型类型参数提供约束T.
3)如果要使用默认构造函数进行实例化,则无需指定空参数集合.这样做:
var v= (InstanceBase)Activator.CreateInstance(typeof(T));
// or just new T();
Run Code Online (Sandbox Code Playgroud)
4)您似乎根本没有在您的GetObject方法中使用任何实例成员.如果是这种情况,那么您可以使用静态方法.这应该是静态还是非静态取决于您想要进行的调用.请static记住.
public static InstanceBase GetObject() //you can make the return type even 'T'
{
var v = new T();
v.Method();
return v;
}
//can call like this too:
ServiceA.GetObject(); //etc
Run Code Online (Sandbox Code Playgroud)