This question already has answers here:
What is the { get; set; } syntax in C#?
(20 answers)
Closed 7 years ago.
I have an strange comportement with my singleton class.
public class HttpCommunicator{
public const int TYPEJSON = 1;
private static HttpCommunicator;
private bool TypeIsInit = false;
public static HttpCommunicator Instance {
get{
if( instance == null ){
instance = new HttpCommunication();
}
return instance;
}
}
private HttpCommunicator(){}
public int RequestType {get {return RequestType;} set{ this.RequestType = value; TypeIsInit = true;}
}
And later in another class i call this
HttpComminicator.Instance.RequestType = HttpCommunicator.TYPEJSON;
My app get stuck/freeze and my debugger don't show me any error. But if I change the get;set; method for this attribut to:
public int GetRequestType(){
return RequestType;
}
public void SetRequestType(int value){
RequestType = value;
TypeIsInit = true;
}
everything works like a charm.
Anybody can explain me why I get this?
Check out your property:
public int RequestType
{
get { return RequestType; }
set { this.RequestType = value; TypeIsInit = true; }
}
You have a bunch of problems here.
What happens when you get that property?
RequestType.get is going to execute, which in turn is going to return RequestType;. To return RequestType you must read RequestType, which will trigger RequestType.get and the loop will go on and on and on and on.
My point is that you're trying to return a property by returning said property, which will probably end up causing a StackOverflowException.
The same can be said about your set accessor.
To fix this, have private fields behind the scenes:
private int _requestType;
public int RequestType
{
get { return _requestType; }
set { _requestType = value; TypeIsInit = true; }
}
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; }
This question already has answers here:
A property or indexer may not be passed as an out or ref parameter
(9 answers)
Closed 5 years ago.
So I have this class that holds 3 counters:
public class Files
{
private static ObservableCollection<Files> _files = new ObservableCollection<Files>();
private static int _inProcess;
private static int _finished;
private static int _inQueue;
public static ObservableCollection<Files> List
{
get { return _files ; }
set { _files = value; }
}
public static int InProcess
{
get { return _inProcess; }
set
{
_inProcess = value;
}
}
public static int Finished
{
get { return _finished; }
set
{
_finished = value;
}
}
public static int InQueue
{
get { return _inQueue; }
set
{
_inQueue = value;
}
}
}
And from another class I want to add value to this fields:
Interlocked.Increment(ref Files.InProcess);
But got this error:
A property or indexer may not be passed as an out or ref parameter.
This works fine:
Files.InProcess++;
How can i fix it ?
The error is pretty straightforward. You can't pass a property as ref. In this case the best option is to create a method
public static void IncrementInProcess()
{
Interlocked.Increment(ref _inProcess);
}
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.
This question already has answers here:
Overloading getter and setter causes a stack overflow in C# [duplicate]
(4 answers)
Closed 3 years ago.
class Program
{
static void Main(string[] args)
{
something s = new something();
s.DoIt(10);
Console.Write(s.testCount);
}
}
class something
{
public int testCount
{
get { return testCount; }
set { testCount = value + 13; }
}
public void DoIt(int val)
{
testCount = val;
}
}
Is what I have, because I was wanting to test and play around with the getters/setters stuff for C#. However, I get a StackOverFlowException was unhandled at "set { testCount = value + 13}". And I can't step through it, as I get a "The debugger cannot continue running the process. Process was terminated" message from Visual Studio. Any ideas what I'm doing wrong?
Edit: Today I've learned that I've done a pretty stupid derp. Given the multitudes of instant responses. Now I know better.
You have an infinite recursion, as you are referring to the property in the property.
You should use a backing field for this:
private int testCount;
public int TestCount
{
get { return testCount; }
set { testCount = value + 13; }
}
Note the property name TestCount (which also conforms to C# naming standard), as opposed to the field name testCount (lowercase t).
You should declare a variable to back the property:
class something
{
private int _testCount;
public int testCount
{
get { return _testCount; }
set { _testCount = value + 13; }
}
...
You have a circular reference in your property's getter. Try this:
class Something
{
private int _testCount;
public int TestCount
{
get { return _testCount; }
set { _testCount = value; }
}
public void DoIt(int val)
{
_testCount = val;
}
}
This:
public int testCount
{
get { return testCount; }
it returns itself, which causes it to execute itself.
Instead of return the own property in itself, store the intended value in another (preferably protected or private) variable. Then manipulate that variable both in the setter and in the getter.
class Program
{
static void Main(string[] args)
{
something s = new something();
s.DoIt(10);
Console.Write(s.testCount);
}
}
class something
{
private int _testCount;
public int testCount
{
// you are calling the property within the property which would be why you have a stack overflow.
get { return _testCount; }
set { _testCount = value + 13; }
}
public void DoIt(int val)
{
testCount = val;
}
}
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.