【发布时间】:2016-03-31 15:15:00
【问题描述】:
在我的项目中,我有实现自定义属性的类层次结构。这里更接近我想要的控制台应用程序版本。
class Property
{
string key;
object value;
public Property(string key, object value)
{
this.key = key;
this.value = value;
}
public override string ToString()
{
return "(key=" + key + ": value=" + value + ")";
}
}
public struct PropertyConfig
{
public string key;
public object defaultValue;
}
abstract class BaseClass
{
Dictionary<string, Property> properties = new Dictionary<string, Property>();
Dictionary<string, PropertyConfig> mergedConfigs = new Dictionary<string, PropertyConfig>();
public BaseClass()
{
MergeWithInheritedConfigsAndCreateInstances(
new PropertyConfig[]
{
new PropertyConfig() { key = "p1", defaultValue = "v1" },
new PropertyConfig() { key = "p2", defaultValue = "v2" }
},
true);
}
protected void MergeWithInheritedConfigsAndCreateInstances(PropertyConfig[] configs = null, bool IsBaseClass = false)
{
configs = configs ?? new PropertyConfig[] { };
foreach (PropertyConfig config in configs)
{
mergedConfigs[config.key] = config;
}
if (!IsBaseClass)
{
CreatePropertyInstancesAfterMerge();
}
}
private void CreatePropertyInstancesAfterMerge()
{
foreach (KeyValuePair<string, PropertyConfig> kvp in mergedConfigs)
{
PropertyConfig config = kvp.Value;
properties.Add(config.key, new Property(config.key, config.defaultValue));
}
}
public override string ToString()
{
return GetType().Name + ".Properties: " + string.Join(",", properties.Select(kvp => kvp.Value.ToString()).ToArray());
}
}
class DerivedClassA : BaseClass
{
public DerivedClassA(): base()
{
MergeWithInheritedConfigsAndCreateInstances();
}
}
class DerivedClassB : BaseClass
{
public DerivedClassB() : base()
{
MergeWithInheritedConfigsAndCreateInstances(new PropertyConfig[]
{
new PropertyConfig() { key = "p2", defaultValue = true },
new PropertyConfig() { key = "p3", defaultValue = "v3" }
});
}
}
class DerivedClassC : BaseClass
{
public DerivedClassC() : base()
{
MergeWithInheritedConfigsAndCreateInstances(new PropertyConfig[]
{
new PropertyConfig() { key = "p2", defaultValue = false },
new PropertyConfig() { key = "p4", defaultValue = "v4" }
});
}
}
class Program
{
static void Main(string[] args)
{
DerivedClassA derivedA = new DerivedClassA();
DerivedClassB derivedB = new DerivedClassB();
DerivedClassC derivedC = new DerivedClassC();
Console.WriteLine(derivedA.ToString());
Console.WriteLine(derivedB.ToString());
Console.WriteLine(derivedC.ToString());
Console.ReadLine();
}
}
基本抽象类定义了其属性对象的配置,这些属性对象旨在在派生类中继承。
在构造函数配置数组中传递给MergeWithInheritedConfigsAndCreateInstances方法调用,第二个参数设置为true,表示属性对象的实例化必须推迟。
合并属性配置的当前状态存储在mergedConfigs Dictionary 中。
派生类传递本地属性配置以与基类配置合并/覆盖,在其构造函数中调用MergeWithInheritedConfigsAndCreateInstances 方法,第二个参数设置为其默认值false,表示现在必须在合并后创建属性实例。
结果输出如下。
DerivedClassA.Properties: (key=p1: value=v1),(key=p2: value=v2)
DerivedClassB.Properties: (key=p1: value=v1),(key=p2: value=True),(key=p3: value=v3)
DerivedClassC.Properties: (key=p1: value=v1),(key=p2: value=False),(key=p4: value=v4)
这正是我所需要的,但这个解决方案有一些我不喜欢的缺点:
1) 必须在每个构造函数中调用MergeWithInheritedConfigsAndCreateInstances。第二个参数必须在抽象类构造函数中提供。
我想要一个解决方案,其中所有合并/实例化机制都在基类中实现和调用。并且能够定义派生类特定的属性配置,而不是作为方法参数,而是作为成员字段/属性(可能是静态的?)。
2) 每次实例化类时都会完成合并过程。
我宁愿只做一次。 (放在静态构造函数中?)
UPD:重写的示例代码更好地展示了预期的想法。
【问题讨论】:
-
仅供参考:这就是 XAML/WPF 在具有依赖属性的底层工作方式...
-
在我的代码中,我不能依赖 wpf 结构。尽管需求看起来相似,但 wpf 依赖属性系统的内部实现高度特定于其域,并且实现细节不能按原样重用。
-
这不是关于重用他们的具体类,而是它背后的想法......:/
标签: c# oop design-patterns extensibility