C#getter和setter速记

C#getter和setter速记,c#,getter-setter,shorthand,C#,Getter Setter,Shorthand,如果我对该生产线内部工作的理解是正确的: public int MyInt { get; set; } 然后它在幕后做这件事: private int _MyInt { get; set; } Public int MyInt { get{return _MyInt;} set{_MyInt = value;} } 我真正需要的是: private bool IsDirty { get; set; } private int _MyInt { get; set; } Pub

如果我对该生产线内部工作的理解是正确的:

public int MyInt { get; set; }
然后它在幕后做这件事:

private int _MyInt { get; set; }
Public int MyInt {
    get{return _MyInt;}
    set{_MyInt = value;}
}
我真正需要的是:

private bool IsDirty { get; set; }

private int _MyInt { get; set; }
Public int MyInt {
    get{return _MyInt;}
    set{_MyInt = value; IsDirty = true;}
}
但我想写一些类似的东西:

private bool IsDirty { get; set; }

public int MyInt { get; set{this = value; IsDirty = true;} }
这是行不通的。问题是,我需要对一些对象执行IsDirty操作,这些对象有几十个属性,我希望有一种方法可以使用自动getter/setter,但在修改字段时仍然设置IsDirty


这是可能的还是我必须让自己的类中的代码量增加三倍?

创建一个IsDirty装饰器(设计模式)来包装一些需要IsDirty标志功能的属性

public class IsDirtyDecorator<T>
{
    public bool IsDirty { get; private set; }

    private T _myValue;
    public T Value
    {
        get { return _myValue; }
        set { _myValue = value; IsDirty = true; }
    }
}

public class MyClass
{
    private IsDirtyDecorator<int> MyInt = new IsDirtyDecorator<int>();
    private IsDirtyDecorator<string> MyString = new IsDirtyDecorator<string>();

    public MyClass()
    {
        MyInt.Value = 123;
        MyString.Value = "Hello";
        Console.WriteLine(MyInt.Value);
        Console.WriteLine(MyInt.IsDirty);
        Console.WriteLine(MyString.Value);
        Console.WriteLine(MyString.IsDirty);
    }
}
public class IsDirtyDecorator<T>
{
    private T _myValue;
    private Action<bool> _changedAction;

    public IsDirtyDecorator<T>(Action<bool> changedAction = null)
    {
        _changedAction = changedAction;
    }

    public bool IsDirty { get; private set; }

    public T Value
    {
        get { return _myValue; }
        set
        {
            _myValue = value;
            IsDirty = true;
            if(_changedAction != null)
                _changedAction(IsDirty);
        }
    }
}
公共类IsDirtyDecorator
{
公共bool IsDirty{get;私有集;}
私人T_myValue;
公共价值
{
获取{return\u myValue;}
设置{u myValue=value;IsDirty=true;}
}
}
公共类MyClass
{
private IsDirtyDecorator MyInt=new IsDirtyDecorator();
private IsDirtyDecorator MyString=new IsDirtyDecorator();
公共MyClass()
{
MyInt.Value=123;
MyString.Value=“你好”;
Console.WriteLine(MyInt.Value);
控制台写入线(MyInt.IsDirty);
Console.WriteLine(MyString.Value);
Console.WriteLine(MyString.IsDirty);
}
}

您需要自己处理这个问题:

private bool IsDirty { get; set; }

private int _myInt; // Doesn't need to be a property
Public int MyInt {
    get{return _myInt;}
    set{_myInt = value; IsDirty = true;}
}
在仍然使用自动属性机制的情况下,没有向setter添加自定义逻辑的语法可用。您需要使用自己的支持字段编写此文件


这是一个常见问题—例如,在实现
INotifyPropertyChanged

我创建了一个自定义的
属性
类来执行这样的常见操作。虽然我还没有完全使用它,但是它可以在这个场景中使用

代码可在此处找到:

您可以按如下方式使用它:

readonly Property<int> _myInt = new Property<int>();
public int MyInt
{
    get { return _myInt.GetValue(); }
    set { _myInt.SetValue( value, SetterCallbackOption.OnNewValue, SetDirty ); }
}

private void SetDirty( int oldValue, int newValue )
{
    IsDirty = true;
}
readonly属性_myInt=new属性();
公共整数MyInt
{
获取{return _myInt.GetValue();}
set{u myInt.SetValue(value,SetterCallbackOption.OnNewValue,SetDirty);}
}
私有void SetDirty(int-oldValue、int-newValue)
{
IsDirty=true;
}
由于
SetterCallbackOption
参数,属性类仅处理在传递新值时调用传递的委托。这是默认设置,因此可以删除它

更新:


当您需要支持多种类型(除了
int
)时,这显然不起作用,因为此时委托将不匹配。当然,您可以随时调整代码以满足您的需要。

您可以使其简单或复杂。这取决于你想投资多少工作。您可以使用面向方面编程通过IL weaver将方面添加到IL代码中,例如。 或者,您可以创建一个简单的类来处理属性的状态。这是如此简单,前一种方法只有在您有很多属性需要以这种方式处理时才有回报

using System;

class Dirty<T>
{
    T _Value;
    bool _IsDirty;

    public T Value
    {
        get { return _Value; }
        set
        {
            _IsDirty = true;
            _Value = value;
        }
    }

    public bool IsDirty
    {
        get { return _IsDirty; }
    }

    public Dirty(T initValue)
    {
        _Value = initValue;
    }
}

class Program
{
    static Dirty<int> _Integer;
    static int Integer
    {
        get { return _Integer.Value; }
        set { _Integer.Value = value;  }
    }

    static void Main(string[] args)
    {
        _Integer = new Dirty<int>(10);
        Console.WriteLine("Dirty: {0}, value: {1}", _Integer.IsDirty, Integer);
        Integer = 15;
        Console.WriteLine("Dirty: {0}, value: {1}", _Integer.IsDirty, Integer);
    }
}
你的,
阿洛伊斯·克劳斯

我将补充西蒙·休斯的答案。我提出了同样的建议,但添加了一种方法,允许decorator类自动更新全局IsDirty标志。您可能会发现用老式的方法进行操作不那么复杂,但这取决于您公开的属性数量以及需要相同功能的类数量

public class IsDirtyDecorator<T>
{
    public bool IsDirty { get; private set; }

    private T _myValue;
    public T Value
    {
        get { return _myValue; }
        set { _myValue = value; IsDirty = true; }
    }
}

public class MyClass
{
    private IsDirtyDecorator<int> MyInt = new IsDirtyDecorator<int>();
    private IsDirtyDecorator<string> MyString = new IsDirtyDecorator<string>();

    public MyClass()
    {
        MyInt.Value = 123;
        MyString.Value = "Hello";
        Console.WriteLine(MyInt.Value);
        Console.WriteLine(MyInt.IsDirty);
        Console.WriteLine(MyString.Value);
        Console.WriteLine(MyString.IsDirty);
    }
}
public class IsDirtyDecorator<T>
{
    private T _myValue;
    private Action<bool> _changedAction;

    public IsDirtyDecorator<T>(Action<bool> changedAction = null)
    {
        _changedAction = changedAction;
    }

    public bool IsDirty { get; private set; }

    public T Value
    {
        get { return _myValue; }
        set
        {
            _myValue = value;
            IsDirty = true;
            if(_changedAction != null)
                _changedAction(IsDirty);
        }
    }
}
公共类IsDirtyDecorator
{
私人T_myValue;
私人行动(变化);;
公共IsDirtyDecorator(Action changedAction=null)
{
_changedAction=changedAction;
}
公共bool IsDirty{get;私有集;}
公共价值
{
获取{return\u myValue;}
设置
{
_我的价值=价值;
IsDirty=true;
如果(_changedAction!=null)
_变更(IsDirty);
}
}
}
现在,您可以让decorator类自动更新另一个类中的某些其他IsDirty属性:

class MyObject
{
    private IsDirtyDecorator<int> _myInt = new IsDirtyDecorator<int>(onValueChanged);
    private IsDirtyDecorator<int> _myOtherInt = new IsDirtyDecorator<int>(onValueChanged);

    public bool IsDirty { get; private set; }

    public int MyInt
    {
        get { return _myInt.Value; }
        set { _myInt.Value = value; }
    }

    public int MyOtherInt
    {
        get { return _myOtherInt.Value; }
        set { _myOtherInt.Value = value; }
    }

    private void onValueChanged(bool dirty)
    {
        IsDirty = true;
    }

}
类MyObject
{
私有IsDirtyDecorator _myInt=新的IsDirtyDecorator(onValueChanged);
private IsDirtyDecorator\u myOtherInt=新的IsDirtyDecorator(onValueChanged);
公共bool IsDirty{get;私有集;}
公共整数MyInt
{
获取{return\u myInt.Value;}
设置{u myInt.Value=Value;}
}
公共互联网
{
获取{return\u myOtherInt.Value;}
设置{u myOtherInt.Value=Value;}
}
私有void onValueChanged(bool dirty)
{
IsDirty=true;
}
}

改用IronPython。它位于CLR上,但支持面向方面的编程,这正是您所需要的。:)如果你使用的是Visual Studio,你至少可以创建一个代码片段来帮助你节省时间。这正是他试图避免做的:)@Nathan:Yep-但这确实是他必须要做的-自动道具不能与自定义逻辑一起工作。这就是说,我的实现不同于OP的——我使用了一个字段,而不是一个自动道具作为支持字段。谢谢你的字段注释。没问题,我刚刚意识到我可能还应该在那里添加一个if(_MyInt!=value)检入,所以我只能用冗长的方式来做:)没有两个字段你就不能这样做吗?如果有,你能更新这个吗?很有趣。问题是,我的对象有很多属性,我真的只想要一个IsDirty。当我的任何属性被更新时,我希望无论哪个属性被更新,都将IsDirty设置为true。这是否仍然适用于您的代码?一次只适用于一个属性。每个属性都有自己的IsDirty标志。如果希望所有属性都有一个IsDirty标志,如果希望每个属性都有一个IsDirty标志,则必须修改Decortor以保存对IsDirty标志的引用。