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标志的引用。