代码之家  ›  专栏  ›  技术社区  ›  Craig.Nicol

具有重复代码的c#属性

  •  5
  • Craig.Nicol  · 技术社区  · 16 年前

    public string Name
    {
        get { return _name; }
        set { IsDirty = true; _name = value; }
    }
    

    如果我可以依靠C#3.0为这些生成备份存储,那会容易得多,但是有没有办法计算出IsDirty=true;这样我就可以这样写我的属性,并且仍然可以得到相同的行为:

    [MakesDirty]
    public string Name { get; set; }
    
    10 回复  |  直到 16 年前
        1
  •  5
  •   Gishu    16 年前

    不,如果没有编写比原始版本多得多的(神秘的?)代码 (您必须使用反射来检查属性上的属性,还有什么没有..我有没有提到它是“较慢的”)。。这是我可以忍受的复制品。

    MS也有同样的需求 raising events when a property is changed . INotifyPropertyChanged是更改通知的重要接口。我见过的每一个实现 做

    set
    { 
      _name = value; 
      NotifyPropertyChanged("Name"); 
    }
    

    如果可能的话,我想微软的那些聪明人已经有了类似的东西。。

        2
  •  3
  •   Joel Coehoorn    16 年前

    您可以尝试设置一个代码段,以便轻松创建这些代码段。

        3
  •  3
  •   Pop Catalin    16 年前

    如果您真的想这样做,要修改代码使用属性所做的事情,有一些方法可以做到这一点,它们都与AOP(面向方面编程)相关。退房 PostSharp ,这是一个后编译器,可以在后编译步骤中修改代码。例如,可以为属性(或方面,在AOP中如何调用)设置一个自定义属性,该属性在属性设置器中注入代码,将对象标记为脏对象。如果您想了解如何实现这一点的一些示例,可以查看他们的 tutorials .

    有更多的AOP框架,一些使用后期编译,一些使用.Net中存在的方法拦截机制,后者与前者相比有一些性能缺陷。

        4
  •  2
  •   Scott Dorman    16 年前

    不,当您使用自动属性时,您对实现没有任何控制权。最好的选择是使用模板工具、代码片段或创建私有SetValue <T &燃气轮机;(ref T backingField,T value),它封装了setter逻辑。

    private void SetValue<T>(ref T backingField, T value)
    {
       if (backingField != value)
       {
          backingField = value;
          IsDirty = true;
       }
    }
    
    public string Name
    {
       get
       {
          return _name;
       }
       set
       {
          SetValue(ref _name, value);
       }
    }
    
        5
  •  0
  •   LepardUK    16 年前

    另一种选择可能是代码生成器,如codesmith,用于自动创建属性。如果要创建的属性是数据库表中的列,这将特别有用

        6
  •  0
  •   JRoppert    16 年前

    我可以推荐使用 Enterprise Library 为此目的。例如,每当您输入/退出一个方法时,策略应用程序块就会提供执行“某事”的基础结构(something=您可以自己编写代码)。可以使用属性控制行为。以此作为一个提示,您可以详细了解企业库的文档。

        7
  •  0
  •   Rob    16 年前

    有一个DefaultValueAttribute可以指定给属性,这主要由设计器工具使用,以便它们可以指示属性何时更改,但是,它可能是一种“整洁”的方式,用于描述属性的默认值,从而能够识别属性是否更改。

    警告:您无法判断属性是否已从非默认值更改回默认值。

        8
  •  0
  •   Thomas Lundström    16 年前

    我认为解决这个问题的最好方法是使用面向方面编程(AOP)。Mats Helander做了一个 write up on this on InfoQ . 这篇文章有点凌乱,但可以照着写。 有许多不同的产品在.NET空间中进行AOP,我推荐PostSharp。

        9
  •  0
  •   Sean Hanley    16 年前

    如果你真的选择了属性,我敢肯定你必须这样做 roll your own logic 推断出它们的含义以及如何处理它们。无论使用什么自定义类对象,都必须有执行这些属性操作/检查的方法,最好是在实例化时。

    否则,您将考虑使用maybe事件。您仍然需要将事件添加到每个set方法中,但这样做的好处是您不必硬编码如何处理每个属性上的脏集,并且可以在一个位置控制要执行的操作。这至少会引入更多的代码重用。

        10
  •  0
  •   dtlvd Dean Poulin    6 年前

    上下文绑定对象。如果创建一个扩展上下文绑定对象的类并创建一个ContextAttribute,则可以截获对此类属性的调用并设置IsDirty。NET将为您的类创建一个代理,以便所有调用都通过类似远程处理接收器的方式进行。

    class A
    {
        [Foo]
        public int Property1{get; set;}
        public int Property2{get {return variable;} set{ Property1 = value; variable = value; }
    }
    

    当从另一个类调用property1时,将调用您的代理。但是,如果另一个类调用property2,即使property2集将调用property1,也不会调用任何代理(当您在该类中时,不需要代理)。