C#替代静态类的继承[重复]

Posted

技术标签:

【中文标题】C#替代静态类的继承[重复]【英文标题】:C# alternative to inheritance for static class [duplicate] 【发布时间】:2020-10-30 16:05:45 【问题描述】:

我有一个静态类,其中包含几个用于管理不同常量的子类。 非常不同的类我想仅根据定义的常量来实现相同的属性。

看起来像这样:

public static class A

    public static class Subclass1
    
        public const int Constant1 = 0;
        public const int Constant2 = 1;

        public static List<int> Elements
         get  return new List<int>  Constant1, Constant2  

        public static int Sum  get  return Elements.Sum();  
        public static int NegSum  get  return -Elements.Sum();  
    

    public static class Subclass2
    
        public const int Constant3 = 3;
        public const int Constant4 = 4;

        public static List<int> Elements
         get  return new List<int>  Constant3, Constant4  

        public static int Sum  get  return Elements.Sum();  
        public static int NegSum  get  return -Elements.Sum();  
    

以便我可以通过

轻松访问它们
int a = A.Subclass1.Constant1;
List<int> b = A.Subclass1.Elements;
int c = A.Subclass1.Sum;

SumNegSum 属性的代码始终相同。 你看到了问题:我需要再次为每个子类包含它们。有没有办法重用属性的代码而不为每个类实现它们?

我想做的是这样的:

public abstract class Base

    public abstract static List<int> Elements  get; 
    public static int Sum  get  return Elements.Sum();  
    public static int NegSum  get  return -Elements.Sum();  


public static class B

    public static class Subclass1 : Base
    
        const int Constant1 = 0;
        const int Constant2 = 1;

        public override static List<int> Elements
         get  return new List<int>  Constant1, Constant2  

    

    public class Subclass2 : Base
    
        const int Constant3 = 0;
        const int Constant4 = 1;
        public override static List<int> Elements
         get  return new List<int>  Constant3, Constant4  
    

嗯,我知道在 C# 中,这样的继承不适用于静态类。 有没有其他聪明的方法来实现这一点?

【问题讨论】:

【参考方案1】:

也许尝试不使用 static 关键字实现 Subclass1 和 Subclass2。像这样

public abstract class Base

public Base(params int[] elements)

this.Elements = new List<int>(elements);

public List<int> Elements  get; private set; 
public virtual int Sum  get  return Elements.Sum();  
public virtual int NegSum  get  return -Elements.Sum();  


public static class B

    public static class Subclass1 : Base
    
        const int Constant1 = 0;
        const int Constant2 = 1;

        public Subclass1() : base(Constant1, Constant2)    
    

    public class Subclass2 : Base
    
        const int Constant3 = 0;
        const int Constant4 = 1;
        public Subclass2() : base(Constant3, Constant4)  
    

然后给B类添加两个静态属性

public static Subclass1 InstanceSubclass1 get; private set
public static Subclass2 InstanceSubclass2 get; private set

最后将静态构造函数添加到B类

static B()

InstanceSubclass1 = new Subclass1 ();
InstanceSubclass2 = new Subclass2 ();

您现在可以通过使用访问您的课程

B.InstanceSubclass1

【讨论】:

您的解决方案的问题是:您不能在 Base 中的 Elements 属性中将抽象与静态结合 哦。对不起。然后,您应该将 Elements、Sum 和 NegSum 设为非静态属性,并根据每个派生类的值填充 Elements 集合。 我刚刚更新了解决方案。【参考方案2】:

如果没有一些代码重复,您将无法实现您想要的。 C# 不以相同的方式处理 static 的继承。虽然您不能 override 超类的静态成员,但您可以使用 new 隐藏和重新实现它。这样做的缺点是你失去了abstract 提供的子类型契约,但是如果你真的希望你的类型是“抽象的”并且有静态成员,那么你在这方面几乎是 SOL。

public class Base 

    public static List<int> Elements  get; 
    public static int Sum(List<int> Elements) => Elements.Sum();
    public static int NegSum(List<int> Elements) => -Elements.Sum();


public static class B

    public sealed class Subclass1 : Base
    
        const int Constant1 = 1;
        const int Constant2 = 2;

        public static new List<int> Elements
         get => new List<int>  Constant1, Constant2 ; 
        public static new int Sum  get => Base.Sum(Elements); 
        public static new int NegSum  get => Base.NegSum(Elements); 

    

    public sealed class Subclass2 : Base
    
        const int Constant3 = 3;
        const int Constant4 = 4;
        public static new List<int> Elements
         get => new List<int>  Constant3, Constant4 ; 
        public static new int Sum  get => Base.Sum(Elements); 
        public static new int NegSum  get => Base.NegSum(Elements); 
    

另一种方法是,您可以使用单例模式来创建您正在实现您想要实现的目标的错觉。就智能感知而言,这将产生与访问B.Subclass1.Sum 等成员完全相同的效果。缺点是这也会暴露 _Subclass1_Subclass2 类并污染命名空间,但您只需要决定这是否是一个可以接受的权衡。

public abstract class Base 

    public abstract List<int> Elements  get; 
    public int Sum  get => Elements.Sum(); 
    public int NegSum  get => -Elements.Sum(); 


public static class B

    public static _Subclass1 Subclass1  get;  = new _Subclass1();
    public static _Subclass2 Subclass2  get;  = new _Subclass2();
    
    public sealed class _Subclass1 : Base
    
        const int Constant1 = 1;
        const int Constant2 = 2;

        public override List<int> Elements
         get => new List<int>  Constant1, Constant2 ; 

    

    public sealed class _Subclass2 : Base
    
        const int Constant3 = 3;
        const int Constant4 = 4;
        public override List<int> Elements
         get => new List<int>  Constant3, Constant4 ; 
    

【讨论】:

【参考方案3】:

如果您不想拥有基类,可以使用接口和扩展方法:

public interface IElementsHost

    List<int> Elements  get; 


public static class ElementsExtensions

    public static int Sum(this IElementsHost host) => host.Elements.Sum();
    public static int NegSum(this IElementsHost host) => -host.Elements.Sum();


public class Host : IElementsHost

     public const int Constant1 = 2;
     public const int Constant2 = 3;

     public List<int> Elements  get;  
         = new List<int>(new int[] Constant1, Constant2 );



// client code
var host = new Host();
var sum = host.Sum();

如果您希望相关子类具有此类功能,则必须使用组合来实现。它看起来像:

public static class OtherStaticClass

     public static ElementHost  get;  = new Host();

     static OtherStaticClass()
     
         Host.Elements.Add(/* some constant, etc. */);
     



// client code
var sum = OtherStaticClass.ElementHost.Sum();

【讨论】:

以上是关于C#替代静态类的继承[重复]的主要内容,如果未能解决你的问题,请参考以下文章

C# 学习笔记 继承

java基础第五天_静态代码块类的继承和接口

解析在C#中接口和类的异同

请教一下C#中父类静态构造函数在子类中为啥不会和子类的静态构造函数一起执行

c#基础知识 类的继承 修饰符

C#父类实现接口,子类继承父类怎么写?