在工作中,我们有一个非常复杂的数据结构,TComplex:
result: Object
最近通过向多个节点类型添加枚举ParsedValue进行了修改。
public class TComplex
{
public AType AType { get; set; }
public BType BType { get; set; }
public IList<CType> CTypes { get; set; }
}
public class AType
{
public int AInteger { get; set; }
public int BInteger { get; set; }
public string AString { get; set; }
}
public class BType
{
public string AString { get; set; }
public IList<DType> DTypes { get; set; }
}
public class CType
{
public int Id { get; set; }
public string Value { get; set; }
}
public class DType
{
public string Value { get; set; }
}
首先,给定TComplex类型的对象,我将如何走分层次结构并产生ParsedValue的所有值:
public enum ParsedValue
{
Parsed,
Interpreted,
Guessed,
Explicit
}
public class TComplex
{
public AType AType { get; set; }
public BType BType { get; set; }
public IList<CType> CTypes { get; set; }
}
public class AType
{
public int AInteger { get; set; }
public int BInteger { get; set; }
public string AString { get; set; }
public ParsedValue ParsedValue { get; set; }
}
public class BType
{
public string AString { get; set; }
public IList<DType> DTypes { get; set; }
public ParsedValue ParsedValue { get; set; }
}
public class CType
{
public int Id { get; set; }
public string Value { get; set; }
public ParsedValue ParsedValue { get; set; }
}
public class DType
{
public string Value { get; set; }
}
更进一步,我怎样才能将此对象中的所有ParsedValues设置为特定的ParsedValue ,比如ParsedValue.Explicit:
public static IEnumerable<ParsedValue> GetParsedValues(TComplex tComplex)
我有一个天真的GetParsedValues和SetParsedValues实现。但是,如果我要向层次结构中的其他类型添加ParsedValue,那么我还需要更改GetParsedValues和SetParsedValues的实现,我发现它很脆弱:
public static IEnumerable<Action<ParsedValue>> SetParsedValues(TComplex tComplex)
我考虑过反思,但还有更好的方法吗?
答案 0 :(得分:2)
我现在没有看到任何关于你现在这样做的非常令人反感的事情,但是如果你愿意,你可以稍微清理一下。
一个选项可能是为所有类而不是接口编写公共基类ParsedValueProviderBase
。为它提供相同两种方法的虚拟无操作实现:
public virtual IEnumerable<ParsedValue> GetParsedValues()
=> Enumerable.Empty<ParsedValue>();
public virtual IEnumerable<ParsedValue> SetParsedValues(ParsedValue pv)
=> Enumerable.Empty<ParsedValue>();
子类可以覆盖或不覆盖它们。
您还可以编写一个IParsedValueThing
接口,由您的部分或全部类实现:
public interface IParsedValueThing {
IEnumerable<ParsedValue> GetParsedValues();
IEnumerable<ParsedValue> SetParsedValues(ParsedValue pv);
}
让每个人都实现该界面。其中一些就是这样:
public IEnumerable<ParsedValue> GetParsedValues()
=> yield return ParsedValue;
public IEnumerable<ParsedValue> SetParsedValues(ParsedValue pv)
=> yield return ParsedValue = pv;
其他人会把钱递给孩子等等。
如果您可能在除此之外的其他类中使用该接口,那可能是个好主意。您可以编写接口并在ParsedValueProviderBase
中实现它。
答案 1 :(得分:1)
为了使这更通用,您可以让每个类实现一个GetParsedValues和SetParsedValues函数,在您的复杂类型中,您现在可以依赖这些函数的实现,并确保它们返回您想要通过的内容。
这里我只实现了GetParsedValues部分,同样可以应用于SetParsedValues
public class TComplex
{
public AType AType { get; set; }
public BType BType { get; set; }
public IList<CType> CTypes { get; set; }
public IEnumerable<ParsedValue> GetParsedValues()
{
foreach (var parsedValue in AType.GetParsedValues())
yield return parsedValue;
foreach (var parsedValue in BType.GetParsedValues())
yield return parsedValue;
foreach (var cType in CTypes)
foreach (var parsedValue in cType.GetParsedValues())
yield return parsedValue;
}
}
public class AType
{
public int AInteger { get; set; }
public int BInteger { get; set; }
public string AString { get; set; }
public ParsedValue ParsedValue { get; set; }
public IEnumerable<ParsedValue> GetParsedValues()
{
yield return ParsedValue;
}
}
public class BType
{
public string AString { get; set; }
public IList<DType> DTypes { get; set; }
public ParsedValue ParsedValue { get; set; }
public IEnumerable<ParsedValue> GetParsedValues()
{
yield return ParsedValue;
}
}
public class CType
{
public int Id { get; set; }
public string Value { get; set; }
public ParsedValue ParsedValue { get; set; }
public IEnumerable<ParsedValue> GetParsedValues()
{
yield return ParsedValue;
}
}
正如您可以看到的那样,您可以修改类型并只编辑该类型的功能。