背景
我有一个基类BaseObject
,我想在整个应用程序中使用它。 BaseObject
实际上只定义了应用程序中所有对象必须具有的公共Guid
;此外,BaseObject
定义了许多方法来帮助生成属性更改事件。这导致了以下代码:
[DataContract]
public abstract class BaseObject
{
private Guid id;
[DataMember]
public Guid Id
{
get { return id; }
set { ChangeProperty(ref id, value, "Id"); }
}
protected virtual void ChangeProperty<T>(
ref T property,
T value,
string propertyName)
{
// Change the property and generate events
}
}
问题
由于所有对象都必须从BaseObject
继承,这意味着派生类会有一个“固定”的对象。 ChangeProperty
。我想修改ChangeProperty
,以便输出到控制台,我将不得不修改基类。
潜在解决方案
我现在重写的代码如下所示;我有一个单独的类来处理属性更改:
public interface IPropertyChangeHelper
{
void ChangeProperty<T>(
ref T property,
T value,
string propertyName,
PropertyChangingEventHandler changingHandler,
PropertyChangedEventHandler changedHandler);
}
[DataContract]
public abstract class BaseObject
{
// passed in during construction
private readonly IPropertyChangeHelper propertyChangeHelper;
private Guid id;
[DataMember]
public Guid Id
{
get { return id; }
set { ChangeProperty(ref id, value, "Id"); }
}
// Forwarding method
protected virtual void ChangeProperty<T>(
ref T property,
T value,
string propertyName)
{
// Forward to helper
}
}
有人可以提供一些反馈意见,说明我是否继续沿着正确的路线进行可组合性/继承?
答案 0 :(得分:0)
ChangeProperty是虚拟的,所以如果你只是想修改一个继承的(&#34; child&#34;)类的行为,你可以这样做:
[DataContract]
public class MyObject: BaseObject
{
protected virtual void ChangeProperty<T>(
ref T property,
T value,
string propertyName)
{
// Do my own stuff
base.ChangeProperty(property, value, propertyName);
}
}
另一方面,如果你想&#34;修改&#34; (或者更好,我会说 augment )每个BaseObject的ChangeProperty方法,我会按你的方式进行。
我可能会使用更多&#34; general&#34;方法,如:
[DataContract]
public abstract class BaseObject
{
public IPropertyChangeHelper propertyChangeHelper { get; set; }
...
public void ChangeProperty<T>(
ref T property,
T value,
string propertyName)
{
if (propertyChangeHelper != null)
propertyChangeHelper.beforeChange(value, propetyName)
...
if (propertyChangeHelper != null)
propertyChangeHelper.afterChange(value, propetyName)
}
}
相应地修改界面。但取决于个人喜好/交易安全(谁会使用你的课程?)的灵活性。
也就是说,如果您不想使用AOP框架!
您面临的问题非常普遍:具有交叉概念(&#34;方面&#34;)的扩展方法,如日志记录,安全性,ecc ......
C#本身没有AOP功能,但有一些.NET库可以帮助您。 举个例子,请看一下PostSharp,或者访问Castle DynamicProxy,或者再次阅读MSDN上的这篇文章。