在这里使用泛型是否合乎逻辑?

时间:2011-04-06 20:07:12

标签: c# .net generics refactoring

最初的代码是这样的:

public interface IApplicableSystem
{
    string Name { get; }

    void Apply ( );
}

public class Effector
{
    public string Name { get; set; }
}

public class EffectSystem : IApplicableSystem
{
    Effector Internal { get; set; }

    public string Name
    {
        get { return this.Internal.Name; }
    }

    RelayCommand applyCommand;
    public ICommand ApplyCommand
    {
        get
        {
            if ( applyCommand == null )
                applyCommand = new RelayCommand ( p => this.Apply ( ) );

            return applyCommand;
        }
    }

    public void Apply ( )
    {

    }

    public EffectSystem ( Effector value )
    {
        this.Internal = value;
    }
}

因此,有许多不同类型实现IApplicableSystem,它们的不同之处在于它们的Name属性,Apply方法以及内部使用的私有Internal属性的类型上课。

我应该使用泛型来制作它们吗?:

这合理吗?主要是这减少了实现IApplicableSystem的其他类型的代码量。

public abstract class GenericSystem<T> : IApplicableSystem
{
    protected T Internal { get; set; }

    public virtual string Name
    {
        get { return String.Empty; }
    }

    RelayCommand applyCommand;
    public ICommand ApplyCommand
    {
        get
        {
            if ( applyCommand == null )
                applyCommand = new RelayCommand ( p => this.Apply ( ) );

            return applyCommand;
        }
    }

    public virtual void Apply ( )
    {

    }

    public GenericSystem ( T value )
    {
        this.Internal = value;
    }
}

public class EffectSystemGeneric : GenericSystem<Effector>
{
    public override string Name
    {
        get { return GetUniqueName ( base.Internal.Name ); }
    }

    public override void Apply ( )
    {
        Console.WriteLine ( "Do something" );
    }
}

2 个答案:

答案 0 :(得分:2)

是的,这是合理的,但是当覆盖虚拟方法时,您必须使用override关键字,而不是虚拟。您可能希望改为使用通用基类,以强制实现者提供实现。

答案 1 :(得分:1)

是的,通用是有道理的,只是因为Internal属性的类型不同。如果没有,非通用基类也可以正常工作。

如果Name属性始终为Internal.Name,那么您可以声明该类:

public class GenericSystem<T> : IApplicableSystem where T : IName

其中IName是具有Name属性的接口,Effector将实现该接口,因此您可以将Name属性的定义移动到基类而不是在任何地方覆盖它。