C# 向属性访问器添加扩展方法
我们在视图模型中进行了大量INotifyPropertyChanged实现,坦率地说,出于不便和美观的原因,我们已经厌倦了在代码中显式地触发属性更改事件 我想在属性的setter上添加一个扩展,使生成的代码如下所示:C# 向属性访问器添加扩展方法,c#,extension-methods,accessor,C#,Extension Methods,Accessor,我们在视图模型中进行了大量INotifyPropertyChanged实现,坦率地说,出于不便和美观的原因,我们已经厌倦了在代码中显式地触发属性更改事件 我想在属性的setter上添加一个扩展,使生成的代码如下所示: public string LazyAccessor { get; set.notify(); } 有办法做到这一点吗?如果没有,我们能发明一个吗 面向方面编程可以解决您的问题 看。 这里有一些例子: 您的“set.notify()”可以使用一些反射,但我认为这不是一个好
public string LazyAccessor
{
get;
set.notify();
}
有办法做到这一点吗?如果没有,我们能发明一个吗 面向方面编程可以解决您的问题 看。 这里有一些例子: 您的“set.notify()”可以使用一些反射,但我认为这不是一个好的解决方案,您仍然需要实现getter和setter。只能添加到类型中。自动属性上的getter和setter由编译器转换为带有支持变量的方法,因此无法对它们使用扩展方法 有办法做到这一点吗 不,没有,不像你贴的那样。扩展方法操作类型,而不是getter或setter 如果没有,我们能发明一个吗 这需要对C#规范进行修改——这不太可能发生
您还可以采取其他方法来缓解这一问题,例如,使用基类和方法来为您调用boiler plate。它们没有进入4.0,但谣传已包含在5.0中 我发现这种方法很有用。请查看。这将在生成过程中修改代码,使属性实现
INotifyPropertyChanged
模式
这可以作为使用,但不能在电视机上进行。这是一种行动。但是,您可以这样做:
public static class extensions()
{
public static NotifyAccessorSet(this string value) { some code }
}
public class SomeClass()
{
.....
private string mAccessor;
public string LazyAccessor{
get { return mAccessor; }
set { mAccessor = value; mAccessor.NotifyAccessorSet(); }
}
}
这有点出乎我的意料,请记住,扩展方法将应用于所有类型的字符串,因此您可能希望实现自己的返回类型并对其应用扩展方法。然后从lazyaccessor返回该类型。您可以通过重写自定义泛型结构的转换运算符来模拟“类似属性”的行为,而无需手动调用事件。 以下是我的解决方案:
public struct column<TType>
{
private TType _value;
private column(TType value) : this()
{
_value = value;
}
private void Set(TType value)
{
// Implement your custom set-behavior...
}
private TType Get()
{
// Implement your custom get-behavior...
return _value;
}
public override string ToString()
{
return _value.ToString();
}
public static implicit operator column<TType>(TType p)
{
column<TType> column = new column<TType>(p);
column.Set(p);
return column;
}
public static implicit operator TType(column<TType> p)
{
return p.Get();
}
}
公共结构列
{
私有TType_值;
私有列(TType值):this()
{
_价值=价值;
}
专用无效集(t类型值)
{
//实现您的自定义设置行为。。。
}
私有TType Get()
{
//实现您的自定义获取行为。。。
返回_值;
}
公共重写字符串ToString()
{
返回_value.ToString();
}
公共静态隐式运算符列(TType p)
{
列=新列(p);
柱集(p);
返回列;
}
公共静态隐式运算符TType(p列)
{
返回p.Get();
}
}
我使用泛型参数声明结构,以避免转换错误。您可以这样使用它:
public class Test
{
public column<int> kKey;
public column<float> dMoney;
public column<string> cValue;
public Test()
{
kKey = 42;
dMoney = 3.1415926f;
cValue = "May the force be with you!";
}
}
公共类测试
{
公共专栏kKey;
公共栏目资金;
公共栏目价值;
公开考试()
{
kKey=42;
dMoney=3.1415926f;
cValue=“愿原力与你同在!”;
}
}
…我知道,这个问题已经过时了,但它可能会对将来的人有所帮助。另一个有趣的方法。你能看看我的答案,看看这是否可行吗?我珍视你的意见,因为你的声誉高于你。也许它太重了?我想这可能是AOP的前身,比如PostSharp,或者他们不知道PostSharp的存在?@BigM我不太确定这两种方法的具体工作原理。我知道他们都使用IL编织,所以他们在概念上是相似的。我使用NotifyPropertyWeaver的原因是您不需要用属性来混乱您的代码。使用该解决方案是一个很好的理由。PostSharp非常通用,适合解决一个痛点,它肯定会更加简洁@卡德雷尔10我看了看波斯夏普,发现它不够好。这是我的推理,我不确定,但我认为要启动NotifyPropertyEvent,您需要知道原始对象(发送者)和属性名称(本示例中的“LazyAccessor”)。因此,您的代码将使其更加健谈。您将拥有原始对象。。。它将是NotifyAccessorSet函数中的“值”。无论如何。。。只是一个建议。这种方法将实现一个额外的函数调用,这将提供一种在set方法中实现通知的方法。