【问题标题】:Adding an extension method to Property Accessor向属性访问器添加扩展方法
【发布时间】:2016-07-08 15:36:25
【问题描述】:

我们在视图模型中执行了大量的 INotifyPropertyChanged 实现,坦率地说,出于不便和美观的原因,我们已经厌倦了不得不在我们的代码中显式地触发属性更改事件。

我想在我们的属性的 setter 上添加一个扩展,使生成的代码看起来像:

public string LazyAccessor
{
  get;
  set.notify();
}

有没有办法做到这一点?如果没有,我们能发明一个吗?

【问题讨论】:

    标签: c# extension-methods accessor


    【解决方案1】:

    查看NotifyPropertyWeaver。这将在构建过程中修改您的代码,以使您的属性实现INotifyPropertyChanged 模式。

    这可以通过Visual Studio Extension获得

    【讨论】:

    • 我认为这要么是使用 PostSharp 之类的东西的 AOP 的前身,要么他们不知道 PostSharp 的存在?
    • @BigM 我不太确定两者的工作原理。我知道他们都使用 IL Weaving,所以它们在概念上是相似的。我使用 NotifyPropertyWeaver 的原因是你不需要用属性来混乱你的代码。
    • 使用该解决方案的充分理由。 PostSharp是非常通用的,这适合解决一个的痛点,它肯定会更简洁!
    • @cadrell0 我查看了postsharp,发现它需要。这是我的推理simoncropp.com/…
    【解决方案2】:

    面向方面的编程可以解决您的问题。

    Aspect Oriented Programming in C#。 还有一些例子:http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS

    您的“set.notify()”可以与一些反射一起使用,但我认为这不是一个好的解决方案,您仍然需要实现 getter 和 setter。

    【讨论】:

      【解决方案3】:

      Extension methods 只能添加到类型。自动属性上的 getter 和 setter 被编译器转换为带有支持变量的方法,因此无法在它们上放置扩展方法。

      【讨论】:

        【解决方案4】:

        有没有办法做到这一点?

        不,没有,不像你发布的那样。扩展方法在 types 上运行,而不是 getter 或 setter。

        如果没有,我们可以发明一个吗?

        这需要更改 C# 规范 - 不太可能发生。

        您可以采取其他方法来缓解这种情况 - 例如,使用带有方法的基类,该方法将为您调用样板代码。

        【讨论】:

        • 另一种有趣的方法。你能看看我的答案,看看这是否也可行?我重视您的意见,因为您的声誉高于您。也许它太重了?
        【解决方案5】:

        他们没有进入 4.0,但传闻将包含在 5.0 中。

        我发现this 方法很有帮助。

        【讨论】:

          【解决方案6】:

          你无法在片场本身上做到这一点。那是一个动作。但是,您也许可以这样做:

          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(); }
            }
          
          }
          

          这有点出乎我的意料,请记住扩展方法将适用于所有类型的字符串,因此您可能希望实现自己的返回类型并将扩展方法应用于它。然后从惰性访问器返回该类型。

          【讨论】:

          • 我不确定,但我认为要触发 NotifyPropertyEvent,您需要知道原始对象(发件人)和属性名称(本示例中的“LazyAccessor”)。所以你的代码会让它更加健谈。
          • 您将拥有原始对象......它将是 NotifyAccessorSet 函数中的“值”。无论如何......只是一个建议。这种方法将实现一个额外的函数调用,这只是提供了一种在 set 方法中实现通知的方法。
          【解决方案7】:

          您可以通过覆盖自定义通用结构的转换运算符来模拟“类似属性”的行为,而无需手动调用事件。 以下是我的解决方案:

          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();
              }
          }
          

          我使用泛型参数声明结构以避免转换错误。你可以这样使用它:

          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!";
              }
          }
          

          ...我知道,这个问题已经过时了,但它可能会在未来对某人有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-11
            • 1970-01-01
            • 1970-01-01
            • 2015-07-23
            • 2013-05-26
            • 1970-01-01
            相关资源
            最近更新 更多