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; }
Related
I'm trying to get and set a property using the following code.
But the when trying to print the property using Console,it returns an empty string.Why is the property not getting set?
using System;
public class Program
{
public static void Main()
{
myclass x=new myclass();
x.myproperty="test";
Console.WriteLine(x.myproperty);
}
class myclass{
string sample;
public string myproperty
{
get { return sample;}
set {sample=myproperty;}
}
}
}
In setter you should use value to assign new value to underlying field
use this instead
public string myproperty
{
get { return sample; }
set { sample = value; }
}
or in C#7
public string myproperty
{
get => sample;
set => sample = value;
}
Edit
As #bradbury9 mentioned, you can also use auto-implemented properties, of course this is the case if you don't want any other logic in getter and setter than just getting and setting the field, if this is the case you can use below snippet
public string myproperty { get; set; }
value keyword is important for setting the value. In Visual Studio you can use propfull + double tab to avoid such common mistakes. It will create full property through shortcuts.
Here is the solution
public static void Main()
{
myclass x = new myclass();
x.myproperty = "test";
Console.WriteLine(x.myproperty);
}
class myclass
{
string sample;
public string myproperty
{
get { return sample; }
set { sample = value; }
}
}
If you just want to return null instead of empty string. This works even when you deserialize your Json:
class myclass
{
string sample;
[JsonProperty("my_property")]
public string My_property
{
get { return sample; }
set { sample = string.IsNullOrEmpty(value) ? null : value; }
}
}
I have class a that keeps track of video streams, and for simplicity I group like properties in a sub classes using auto properties to access them. I then bound the whole class to an BindingList, but only the None Nested Properties show up. How can i get the Nested Properties to show up also?
public class Stream: : INotifyPropertyChanged
{
public bool InUse {
get { return _inUse; }
set {
_inUse = value;
OnPropertyChanged("InUse");
}
}
}
....
internal SubCodec Codec { get; set; }
internal class SubCodec
{
public string VideoCodec
{
get { return _audioCodec; }
set {
_audioCodec = value;
OnPropertyChanged("AudioCodec");
}
}
....
}
You need to fire OnPropertyChanged of the parent type, not on the child type.
public class Stream : INotifyPropertyChanged
{
private SubCodec _codec;
internal SubCodec Codec
{
get
{
return _codec;
}
set
{
_codec = value;
//note that you'll have problems if this code is set to other parents,
//or is removed from this object and then modified
_codec.Parent = this;
}
}
internal class SubCodec
{
internal Stream Parent { get; set; }
private string _audioCodec;
public string VideoCodec
{
get { return _audioCodec; }
set
{
_audioCodec = value;
Parent.OnPropertyChanged("VideoCodec");
}
}
}
}
It may be simpler to put the Stream in the constructor of SubCodec and not allow it to be changed. It would be one way of avoiding the problems I mention in the comment of the Codec set method.
You need to raise PropertyChanged event on SubCodec
private SubCoded _codec;
internal SubCodec Codec
{
get {return _codec;}
set
{
_codec = value;
OnPropertyChanged("Codec");
}
}
I want to have a default value for a boolean crossover of false
How can I initialize it?
public class DecisionBar
{
public DateTime bartime
{ get; set; }
public string frequency
{ get; set; }
public bool HH7
{get;set;}
public bool crossover
{get;set;}
public double mfe
{get;set;}
public double mae
{get;set;}
public double entryPointLong
{get;set;}
public double entryPointShort
{get;set;}
}
Apart from the fact that the default value is false, there are two options. Obviously they are redundant, but if you wanted the default value to true you could use either method.
Either don't use an auto-implemented property, instead using a backing property;
private bool _crossover = false;
public bool crossover
{
get { return _crossover; }
set { _crossover = value; }
}
or in the constructor;
public DecisionBar()
{
crossover = false;
}
The default value of any bool is false so you really don't need to do anything in this case.
If, however, you wanted true to be the default value, you could have an explicit backing private field of crossover and initialize that to be true:
private bool _co = true;
public bool crossover
{
get { return _co; }
set { _co = value; }
}
private bool _crossover = false;//or true
public bool Crossover {get {return _crossover;}set{_crossover =value;}}
The default value of a boolean is false. I'm not sure what you mean here.
If you want to set it explicitly. Put this in the class.
private bool _crossover = false;
public bool crossover
{
get
{
return _crossover;
}
set
{
_crossover = value;
}
}
from MSDN:
The default value of the bool is false; The default value of a bool? variable is null. Default constructors are invoked by using the new operator, as follows:
var decisionBar = new DecisionBar();
var myBool = decisionBar.crossover; // 'myBool' should be 'false'
The preceding statement has the same effect as the following statement:
var decisionBar = new DecisionBar();
decisionBar.crossover = false;
See this post:
How do you give a C# Auto-Property a default value?
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.
This works:
using System;
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>;
namespace ConsoleApplication2
{
class test
{
public ConstraintSet a { get; set; }
public test()
{
a = new ConstraintSet();
}
static void Main(string[] args)
{
test abc = new test();
Console.WriteLine("done");
}
}
}
This does not:
using System;
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>;
namespace ConsoleApplication2
{
class test
{
public ConstraintSet a { get { return a; } set { a = value; } }
public test()
{
a = new ConstraintSet();
}
static void Main(string[] args)
{
test abc = new test();
Console.WriteLine("done");
}
}
}
I get a stack overflow exception on a's setter in the second class and I do not know why. I cannot use the first form because it is not supported by the Unity game engine.
When you write a = value, you are calling the property setter again.
In order to use non-automatic properties, you need to create a separate private backing field, like this:
ConstraintSet a;
public ConstraintSet A { get { return a; } set { a = value; } }
You haven't declared a backing variable - you've just got a property whose getters and setters call themselves. It's not clear to me why the first form isn't supported by Unity - which means it's possible that the equivalent won't be supported either, but it's basically this:
private ConstraintSet aValue;
public ConstraintSet a { get { return aValue; } set { aValue = value; } }
I'd normally have a more conventional name, of course - which means you can get away without the "value` bit:
private ConstraintSet constraints;
public ConstraintSet Constraints
{
get { return constraints; }
set { constraints = value; }
}
To give a bit more detail as to why your current second form is throwing a StackOverflowException, you should always remember that properties are basically methods in disguise. Your broken code looks like this:
public ConstraintSet get_a()
{
return get_a();
}
public void set_a(ConstraintSet value)
{
set_a(value);
}
Hopefully it's obvious why that version is blowing the stack. The amended version just sets a variable instead of calling the property again, so it looks like this when expanded:
private ConstraintSet aValue;
public ConstraintSet get_a()
{
return aValue;
}
public void set_a(ConstraintSet value)
{
aValue = value;
}
You cannot use the same variable name inside the getter and setter. This will cause it to call itself and will eventually lead to a stack overflow. Too much recursion.
You'll need a backing variable:
private ConstraintSet _a;
public ConstraintSet a { get { return _a; } set { _a = value; } }
You need a private backing variable in your public property:
private ConstraintSet _a;
public ConstraintSet a { get { return _a; } set { _a = value; } }