C# SOLID - 在不违反 Open/Closed 的情况下扩展类并覆盖/隐藏成员?

问题描述

我需要扩展一个类,其中子类不会使用父类的某些成员。未使用的成员应该如何处理,同时仍然尊重开放/封闭的 SOLID 原则?我正在考虑做一些类似于下面的代码的事情,但是使用反射的现有代码会出现异常。如果我将数据放入已弃用的成员中,现有代码会产生意想不到的结果。

我觉得应该使用完全不同的方法。如何在不修改现有代码的情况下处理这种情况(这也会违反开放/封闭原则)?

class Parent
{
    public virtual int myVarMin { get; set; } = 0;
    public virtual int myVarMax { get; set; } = 10;
    public int myVar { get; set; }
    public int unchanged1 {get; set;}
    //.
    //numerous other members that are irrelevant to the question
    //.
    public void doSomething(){/*do something*/}
    //
}

class Child:Parent
{
    //considered impementation from original question 
    public override int myVarMin => throw new NotSupportedException();
    public override int myVarMax => throw new NotSupportedException();
    public List<int> myVarList = new List<int>();
}

class MyExistingCode
{
    public void display(Parent parent)
    {
        foreach (var info in parent.GetType().GetProperties())
        {
            Console.WriteLine($"{info.Name}: {info.GetValue(parent)}");
        }
    }
}

解决方法

使用 Obsolete 属性通知开发人员您的方法已被弃用,他们应该使用新版本。

[Obsolete("Method is deprecated,use Method2 please.")]
public void Method()
{ 
    … 
}

这里我更改了您的代码,因此您可以使用反射检测方法/属性是否已弃用,并且不会再抛出异常。

    public class Parent
    {
        public virtual int myVarMin { get; set; } = 0;
        public virtual int myVarMax { get; set; } = 10;
        public int myVar { get; set; }
    }

    public class Child : Parent
    {
        [Obsolete("Use other property")]
        public override int myVarMin => throw new NotSupportedException();
        [Obsolete("Use other property")]
        public override int myVarMax => throw new NotSupportedException();
        public List<int> myVarList = new List<int>();
    }

    class MyExistingCode
    {
        public void Display(Parent parent)
        {
            foreach (var info in parent.GetType().GetProperties())
            {
                var customeAttributes = (ObsoleteAttribute[])info.GetCustomAttributes(typeof(ObsoleteAttribute),false);
                if (customeAttributes.Length > 0)
                {
                    Console.WriteLine($"{info.Name} is deprecated.");
                }
                else
                {
                    Console.WriteLine($"{info.Name}: {info.GetValue(parent)}");
                }
            }
        }
    }
,

我最终做了这样的事情(ParentMyExistingCode 类没有改​​变,所以它们符合开放/封闭原则):

class Child : Parent
    {
        public new int? myVarMin => null;
        public new int? myVarMax => null;
        public List<int> myVarList = new List<int>();
    }

 class MyNewCode : MyExistingCode
    {
        public new void Display(Parent parent)
        {
            foreach (var info in parent.GetType().GetProperties())
            {
                Console.WriteLine($"{info.Name}: {info.GetValue(parent) ?? "NULL"}");
            }
        }
    }

我很惊讶我可以用 int 隐藏 int? 而不会出错。 如果更好,我会接受另一个答案。