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;
Sum 和 NegSum 属性的代码始终相同。 你看到了问题:我需要再次为每个子类包含它们。有没有办法重用属性的代码而不为每个类实现它们?
我想做的是这样的:
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#替代静态类的继承[重复]的主要内容,如果未能解决你的问题,请参考以下文章