If my understanding of the internal workings of this line is correct:
public int MyInt { get; set; }
Then it behind the scenes does this:
private int _MyInt { get; set; }
Public int MyInt {
get{return _MyInt;}
set{_MyInt = value;}
}
What I really need is:
private bool IsDirty { get; set; }
private int _MyInt { get; set; }
Public int MyInt {
get{return _MyInt;}
set{_MyInt = value; IsDirty = true;}
}
But I would like to write it something like:
private bool IsDirty { get; set; }
public int MyInt { get; set{this = value; IsDirty = true;} }
Which does not work. The thing is some of the objects I need to do the IsDirty on have dozens of properties and I'm hoping there is a way to use the auto getter/setter but still set IsDirty when the field is modified.
Is this possible or do I just have to resign myself to tripling the amount of code in my classes?
You'll need to handle this yourself:
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;}
}
There is no syntax available which adds custom logic to a setter while still using the automatic property mechanism. You'll need to write this with your own backing field.
This is a common issue - for example, when implementing INotifyPropertyChanged.
Create an IsDirty decorator (design pattern) to wrap some your properties requiring the isDirty flag functionality.
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);
}
}
You can make it simple or complex. It depends on how much work you want to invest. You can use aspect oriented programming to add the aspect via an IL weaver into the IL code with e.g. PostSharp.
Or you can create a simple class that does handle the state for your property. It is so simple that the former approach only pays off if you have really many properties to handle this way.
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);
}
}
Another possibility is to use a proxy class which is generated at runtime which does add the aspect for you. With .NET 4 there is a class that does handle this aspect already for you. It is called ExpandObject which does notify you via an event when a property changes. The nice things is that ExpandoObject allows you to define at runtime any amount of properties and you get notifications about every change of a property. Databinding with WPF is very easy with this type.
dynamic _DynInteger = new ExpandoObject();
_DynInteger.Integer = 10;
((INotifyPropertyChanged)_DynInteger).PropertyChanged += (o, e) =>
{
Console.WriteLine("Property {0} changed", e.PropertyName);
};
Console.WriteLine("value: {0}", _DynInteger.Integer );
_DynInteger.Integer = 20;
Console.WriteLine("value: {0}", _DynInteger.Integer);
Yours,
Alois Kraus
I'm going to add on to Simon Hughes' answer. I propose the same thing, but add a way to allow the decorator class to update a global IsDirty flag automatically. You may find it to be less complex to do it the old-fashioned way, but it depends on how many properties you're exposing and how many classes will require the same functionality.
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);
}
}
}
Now you can have your decorator class automatically update some other IsDirty property in another class:
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;
}
}
I have created a custom Property<T> class to do common operations like that. I haven't used it thoroughly yet though, but it could be used in this scenario.
Code can be found here: http://pastebin.com/RWTWNNCU
You could use it as follows:
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;
}
The Property class handles only calling the passed delegate when a new value is passed thanks to the SetterCallbackOption parameter. This is default so it can be dropped.
UPDATE:
This won't work apparently when you need to support multiple types (besides int), because the delegate won't match then. You could ofcourse always adjust the code to suit your needs.
Related
i am trying to set inner class value from outer class using event handler
here the line for passing the value , PaymentMode is Event
public event PaymentModeEven PaymentMode;
PaymentMode(this,new PaymentModeEvenArgs() { paymentSuccess = true });
Inner Class
public class PaymentModeEvenArgs: EventArgs
{
private bool PaymentSuccess;
public bool paymentSuccess
{
get { return paymentSuccess; }
set
{
paymentSuccess = value;
}
}
}
Program get stuck and stopped
You have a stack overflow exception. Consider your property:
public bool paymentSuccess
{
get { return paymentSuccess; }
set
{
paymentSuccess = value;
}
}
When you get or set paymentSuccess, what does it do internally? It gets or sets paymentSuccess. Which, internally, gets or sets paymentSuccess. Which, internally... You get the idea.
It looks like you meant to swap the casing between the field and the property:
private bool paymentSuccess;
public bool PaymentSuccess
{
get { return paymentSuccess; }
set
{
paymentSuccess = value;
}
}
Or, even better, just use an auto-implemented property so you only have to make one named member:
public bool PaymentSuccess { get; set; }
I'm trying to implement a PATCH on Web API for an object that will be stored in a DB. The input object from the controller has all of the properties that can be modified but we allow the client to choose which fields to send back. We only want to update the MongoDB representation if some of the fields have changed or been set. We started using a Dirty object pattern (not sure this is a pattern) whereby when you set a property you also record that it is dirty. for instance
public class Example
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
TitleWasSet = true;
}
}
public bool TitleWasSet {get;set;}
}
This could work but is kind of tedious and I feel it exposes lots of logic that could be contained.
So a solution I came up with was to store the update Actions in the inbound object then reapply them to the Mongo Object in a Try Update fashion.
like this:
public class Data
{
public string Header { get; set; }
public int Rating { get; set; }
}
public class EditDataRequest
{
private readonly List<Action<Data>> _updates;
public EditDataRequest()
{
_updates = new List<Action<Data>>();
}
public string Header
{
set
{
_updates.Add(data => {data.Header = value;});
}
}
public int Rating
{
set
{
_updates.Add(data => {data.Rating = value;});
}
}
public bool TryUpdateFromMe(Data original)
{
if (_updates.Count == 0)
return false;
foreach (var update in _updates)
{
update.Invoke(original);
}
return true;
}
}
Now this would work great but it doesn't take account of the values being the same. So i then looked at changing the list of actions to a list of functions that would return a bool if there was a difference in the value.
private readonly List<Func<Data, bool>> _updates;
And then the properties would look like this:
public int Rating
{
set
{
_updates.Add(data => {
if (data.Rating != value)
{
data.Rating = value;
return true;
}
return false;
});
}
}
And the try update method...
public bool TryUpdateFromMe(Data original)
{
if (_updates.Count == 0)
return false;
bool changesRequired = false;
foreach (var update in _updates)
{
changesRequired |= update.Invoke(original);
}
return changesRequired;
}
As you can see that property set implementation is rather clunky and would make the code nasty to read.
I'd like a way of extracting the check this property value then update it to another method that I can reuse in each property - I assume this is possibly somehow but it might not be.
Of course, if you have better suggestions for how to handle the PATCH situation then I'd be happy to hear them as well.
Thanks for reading this far.
I have a few classes which have some primitive fields and I would like to create a generalized wrapper for them in order to access their fields. This wrapper should somehow contain a reference to the fields of my classes so that I can read/write the values of these fields. The idea is to create a genralized architecture for these classes so that I dont have to write code for each of them. The classes have fields which have a number in them which will be used as an Id to access the fields.
This is some example code that might shed some light on my requirement. What I want in the end is to change the value of some field in the object of Fancy1 class without accessing the object itself but through its wrapper.
class Fancy1
{
public double level1;
public bool isEnable1;
public double level2;
public bool isEnable2;
public double level3;
}
class Fancy2
{
public double level4;
public bool isEnable4;
public double level6;
public bool isEnable6;
public double level7;
}
class FieldWrapper
{
public int id { get; set; }
public object level { get; set; }
public object isEnabled { get; set; }
public FieldWrapper(int id, object level, object isEnabled)
{
this.id = id;
this.level = level;
this.isEnabled = isEnabled;
}
}
class FancyWrapper
{
private Fancy scn;
public FancyWrapper(Fancy scn)
{
if (!(scn is Fancy))
throw new ArgumentException(scn.GetType().FullName + " is not a supported type!");
this.scn = scn;
}
private Dictionary<int, FieldWrapper> fieldLut = new Dictionary<int, FieldWrapper>();
private List<FieldWrapper> _fields { get { return fieldLut.Values.ToList(); } }
public List<FieldWrapper> fields
{
get
{
if (_fields.Count == 0)
{
foreach (System.Reflection.FieldInfo fieldInfo in scn.GetType().GetFields())
{
if (fieldInfo.FieldType == typeof(double))
{
int satId = getIdNr(fieldInfo.Name);
fieldLut.Add(satId, new FieldWrapper(satId, fieldInfo.GetValue(scn), true));
}
}
foreach (System.Reflection.FieldInfo fieldInfo in scn.GetType().GetFields())
{
if (fieldInfo.FieldType == typeof(bool))
{
int satId = getIdNr(fieldInfo.Name);
fieldLut[satId].isEnabled = fieldInfo.GetValue(scn);
}
}
}
return _fields;
}
}
private int getIdNr(string name)
{
System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(name, #"\d+");
return Int32.Parse(m.Value);
}
}
class Program
{
static void Main(string[] args)
{
Fancy1 fancy = new Fancy1();
fancy.level1 = 1;
fancy.isEnable1 = true;
fancy.level2 = 2;
fancy.isEnable2 = false;
fancy.level3 = 3;
FancyWrapper wrapper = new FancyWrapper(fancy);
wrapper.fields[2].level = 10;
// fancy.level2 should somehow get the value I set via the wrapper
Console.WriteLine(fancy.level2);
Console.ReadLine();
}
}
EDIT: Fancy classes cannot be changed since they are part of an interface!
Depending on how many Fancy classes you are dealing with, you could create an adapter/facade class for each the expose a common interface. eg:
class Fancy1
{
public double level1;
public bool isEnable1;
public double level2;
public bool isEnable2;
public double level3;
}
public class FieldWrapper
{
private Action<double> _levelSetter;
private Func<double> _levelGetter;
private Action<bool> _enableSetter;
private Func<bool> _enableGetter;
public double level { get { return _levelGetter(); } set { _levelSetter(value); }}
public bool isEnabled { get { return _enableGetter(); } set { _enableSetter(value); }}
internal FieldWrapper(Func<double> levelGetter, Action<double> levelSetter, Func<bool> enableGetter, Action<bool> enableSetter)
{
_levelGetter = levelGetter;
_levelSetter = levelSetter;
_enableGetter = enableGetter;
_enableSetter = enableSetter;
}
}
abstract class FancyWrapper
{
public FieldWrapper[] Fields { get; protected set; }
}
class Fancy1Wrapper : FancyWrapper
{
private Fancy1 _fancy1;
public Fancy1Wrapper(Fancy1 fancy1)
{
_fancy1 = fancy1;
this.Fields = new[] { new FieldWrapper(() => fancy1.level1, level => _fancy1.level1 = level, () => _fancy1.isEnable1, enable => _fancy1.isEnable1 = enable),
new FieldWrapper(() => fancy1.level2, level => _fancy1.level2 = level, () => _fancy1.isEnable2, enable => _fancy1.isEnable2 = enable), };
}
}
Or you could invest 5 minutes learning data structures. Consider following example:
var levels = new Dictionary<int, bool>
{
{1, true},
{2, false}
};
if (levels[1])
{
//will run, because level 1 is true
}
if (levels[2])
{
//will not run, because level 2 is false
}
if (levels.ContainsKey(3) && levels[3])
{
//will not run, because dictionary does not contain entry for key 3
}
levels.Add(3, false);
if (levels.ContainsKey(3) && levels[3])
{
//will not run, because level 3 is false
}
levels[3] = true;
if (levels.ContainsKey(3) && levels[3])
{
//will run, because level 3 is true
}
That may seem like what you want, but it really isn't. It is extremely awkward on any number of levels. More specifically, pointers are generally rather "Un-C#-like" and having to know about these numbers defeats the point of having separate classes to begin with.
Think closely about what you want to accomplish. If you're having problems translating it into code, we're here to help. :)
Ok so I have a problem :/ first off Im using C#.. Next, in the section where you see
public int BaseValue()
{
get{return _basevalue;}
set{_basevalue value; }
}
I get 3 Errors
1) Unexpected symbol `{'
2)Unexpected symbol `{' in class, struct, or interface member declaration
and
3) Parsing Error
and frankly its pissing me off -_- so does anyone know what the problem may be?
public class BaseStats {
private int _basevalue; //base value of this stat
private int _buffvalue; //amount needed to buff the stat
private int _expToLevel; //amount needed to move to the next level
private float _LevelModifier; //the modifier applied to the exp needed to raise the skill
public BaseStats()
{
_basevalue = 0;
_buffvalue = 0;
_expToLevel = 100;
_LevelModifier = 1.1f;
}
//Basic Setters and Getters
public int BaseValue()
{
get{return _basevalue;}
set{_basevalue value; }
}
public int BuffValue()
{
get{return _buffvalue; }
set{_buffvalue value; }
}
public int ExpToLevel()
{
get{return _expToLevel; }
set{_expToLevel.value; }
}
public float LevelModifier()
{
get{return _levelModifier; }
set{_levelModifier.value; }
}
private int CalculateExpToLevel()
{
return (int)(_expToLevel * _levelModifier);
}
public void LevelUp()
{
_expToLevel = CalculateExpToLevel();
_baseValue++;
}
public int AdjustedValue()
{
return _baseValue + _buffValue;
}
}
Properties do not have parentheses. Eliminate the () and fix your setter on what you intend to be properties. Eliminate the get/set on what you intend to be methods.
// this is a property
public int Foo
{
get { return foo; }
set { foo = value; }
}
// this is a method
public decimal Bar()
{
// do something and return a decimal
}
And note, as of C# 3, if your property is a simple get/set operation, you can use auto-implemented properties and eliminate the explicit backing variable.
public int Foo { get; set; }
Take the following struct class:
public struct SingleWraper
{
private double _myValue;
public double MyValue
{
get { return _myValue; }
set { _myValue = value; }
}
public void SetMyValue(double myValue)
{
_myValue = myValue;
}
}
public struct DoubleWraper
{
public SingleWraper SingWraper { get; set; }
public void SetMyValue(double singleVa)
{
SingWraper.SetMyValue(singleVa);
}
}
Run the following test:
[Test]
public void SetMyValue()
{
var singleWraper = new DoubleWraper();
singleWraper.SetMyValue(10);
Assert.AreEqual(10,singleWraper.SingWraper.MyValue);
}
It fails.
However, if you don't use automatic property for DoubleWraper, i.e, you expand the field as below:
public struct DoubleWraper
{
private SingleWraper _singWraper;
public SingleWraper SingWraper
{
get { return _singWraper; }
set { _singWraper = value; }
}
public void SetMyValue(double singleVa)
{
_singWraper.SetMyValue(singleVa);
}
}
Then the test will pass.
Why this is so?
It is here:
_singWraper.SetMyValue(singleVa);
vs:
SingWraper.SetMyValue(singleVa);
In the second, you access a property, therefore you clone the struct; essentially this is the same as:
var clonedAndIndependentValue = SingWraper; // getter
clonedAndIndependentValue.SetMyValue(singleVa);
Note we've updated a different struct value; contrast to field access, which talks to the existing struct value.
Yet another example of why mutable structs are evil. DON'T DO IT. Make the struct immutable (no Set* methods, property setters, or other shenanigans). Or use a class.