问题描述
我需要扩展一个类,其中子类不会使用父类的某些成员。未使用的成员应该如何处理,同时仍然尊重开放/封闭的 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)}");
}
}
}
}
,
我最终做了这样的事情(Parent
和 MyExistingCode
类没有改变,所以它们符合开放/封闭原则):
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?
而不会出错。
如果更好,我会接受另一个答案。