C# SOLID - 在不违反 Open/Closed 的情况下扩展 class 和 override/hide 成员?

C# SOLID - Extend class and override/hide members without violating Open/Closed?

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

我觉得可能应该使用一种完全不同的方法。如何在不修改现有代码的情况下处理这种情况(这也违反了open/closed原则)?

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

这里我更改了你的代码,所以使用反射你可以检测 method/property 是否被弃用,它不会再抛出异常。

    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类没有改变,所以它们符合open/closed原则:

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。 如果更好,我会接受另一个答案。