My C#类作为一组值的持有者,现在存储为属性。为了增加可扩展性,我将添加一个Dictionary,以便人们可以在那里存储他们想要的任何属性,而无需更改类代码。但是,我希望通过允许仍然通过行包访问器或原始的getter setter访问旧属性来保持向后兼容性。即我希望以下两段代码具有相同的效果。
properties.Config1 = value
properties["Config1"] = value
有没有人对此类更改的最佳做法有任何提示?一个复杂因素是一些现有的getter setter中有一些验证/逻辑。
答案 0 :(得分:3)
如果要保留向后兼容性,则不能直接公开Dictionary。相反,您可以在类上实现indexer并在其中放置一些检查,以确保在使用该语法访问其中一个现有属性时运行相应的逻辑。
如果使用索引器执行此操作,则可以选择将现有属性放入Dictionary中,或者只保留原样并在传递相应字符串时从索引器的getter / setter调用现有的getter和setter。一把钥匙。
索引器看起来像这样:
public object this[string key] {
get {
if (key == "Config1") return this.Config1;
else return propBag[key];
}
set {
if (key == "Config1") this.Config1 = value;
else propBag[key] = value;
}
}
当然,您可能希望添加检查以确保密钥存在于else
块中,但这应该可以帮助您入门。
还需要考虑的一件事:更改此类以添加属性包行为,无论是作为公共字典还是索引器实现,都将导致类的接口发生更改。因此,您不必重写现有代码,但是一旦更改了类,您将不得不重新编译。
答案 1 :(得分:1)
使用ExpandoObject
实际上是带有语法糖的字符串/对象字典:
http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx
将properties
作为ExpandoObject
。以下是来自MSDN的示例:
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
foreach (var property in (IDictionary<String, Object>)employee)
{
Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33
答案 2 :(得分:1)
您是否只是将对内部字段'_config1'的引用替换为指向字典存储?你需要实现一些逻辑来检查字典键是否存在等等,但它不应该是变化的巨大。
答案 3 :(得分:0)
我希望自己实现与此类似的东西,向前和向后兼容都是问题。
我希望在我的属性包中使用反射来检查基类是否显式实现了该属性,如果确实如此,那么让Property Bag引用基本实现。
例如,如果我的类实现:
string MyClass.Name
然后,内部属性包将使用反射将MyClass.Properties["Name"]
的请求转发给MyClass.Name
这可能会导致问题。例如,如果我的类的用户设置了ad-hoc属性list(of string) MyClass.Properties["Address"]
,然后我实现了默认属性string Myclass.Address
- 这显然会导致用户代码中断。
这对我正在开发的环境来说不是一个问题。
答案 4 :(得分:0)
以下是一篇关于代码设计某些方面的相当不错的文章,适用于想要创建“PropertyBag”类型的人,以及谁不想要System.Dynamic
的开销
http://www.codeproject.com/Articles/12282/Implementing-a-PropertyBag-in-C