c# - 增强派生功能的基类方法 - 减少代码

标签 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() { }
}

不同的服务处理不同的实例类。但是 GetObject 的代码对于所有服务都是相似的。我想通过扩展执行最多的基类的 GetObject 方法来减少代码库。

class ServiceBase
{
     public virtual InstanceBase GetObject<T>()
     {
         var v= (InstanceBase)Activator.CreateInstance(typeof(T), new object[] { });
         v.Method();
         return v;
     }
}

这好像是一种实现方式。但是我对使用反射不太谨慎,因为它可能会遇到性能问题。有没有更好的方法来实现这一点?

最佳答案

是的,有几种方法:

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> 
{

}

这只是更好,因为它的代码重复最少,但我不确定通用性是否会成为一个麻烦。

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
}

现在从重写的属性 Instance 返回一个新的 InstanceBase 实例或一个已经实例化的实例。这取决于您的逻辑,但从显示的方法看来,您每次都必须返回一个新实例。


哪个适合你取决于你的背景。不管是什么,想想:

1) 这种方法不好。

 public virtual InstanceBase GetObject<T>()
 {
     var v= (InstanceBase)Activator.CreateInstance(typeof(T), new object[] { });
     v.Method();
     return v;
 }

首先,无论何时调用函数,都必须指定类型参数,其次,很可能会把事情搞砸。

ServiceA a = new ServiceA();
a.GetObject<InstanceB>(); // not probably what you want.

2) 在任何情况下,您都可以为泛型类型参数T 提供new() 约束条件。

3) 如果要使用默认构造函数进行实例化,则无需指定空参数集合。这样做:

var v= (InstanceBase)Activator.CreateInstance(typeof(T));
// or just new T();

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

关于c# - 增强派生功能的基类方法 - 减少代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20662800/

相关文章:

javascript - 对于类实例的私有(private)成员是否有更优雅的方法?

python - 如何在Python中创建多个类实例?

WCF 派生类型和违反开闭原则

c# - 为什么我不能继承这个变量?

c++ - 使用抽象类实现派生类的元素栈

c# - 自动登录 Active Directory

c# - 错误: The cast to value type 'System.Int32' failed because the materialized value is null

c# - 使用 * 的 AssemblyVersion 失败,错误为 "wildcards, which are not compatible with determinism?"

ruby - 在 Ruby 中跨类的多个实例内存数据的好方法是什么?

c# - 如何在C#中将EXIF数据写入图像?