So, in some C# code, I have something similar to the two properties:
private string _foo;
private string _bar;
public Foo
{
get;
set {
_foo = value;
Bar = _foo.Substring(3, 5);
}
}
public Bar
{
get;
set {
_bar = value;
Foo = "XXX" + _bar;
}
}
Question: Are C# properties subject to circular references/updates, like this example would seem to cause?
You can avoid the infinite loop by updating the hidden field directly, like this:
private string _foo;
private string _bar;
public string Foo
{
get { return _foo; }
set {
_foo = value;
_bar = _foo.Substring(3, 5);
}
}
public string Bar
{
get { return _bar; }
set {
_bar = value;
_foo = "XXX" + _bar;
}
}
This will bypass the other property's setter, which eliminates the loop.
But... this generally causes maintenance headaches later on. Personally, I'd try to find an alternative design.
Are C# properties subject to circular references/updates, like this example would seem to cause?
Yes. You have a nice, infinite loop here.
Properties in C# are simple methods (getter and setter). You call one method from other method and vice versa. Result is completely expected.
Would this surprise you?
public void set_Foo(string value)
{
set_Bar(value.Substring(3, 5));
}
public void set_Bar(string value)
{
set_Foo("XXX" + value);
}
Call set_Foo("XXX12345") and.. you'll see the name of this site
To avoid the infinite loop, here's an alternative to Philip Hanson's answer: run the setter lines only when the value actually changes. Be nice; this is my first post/answer
private string _foo;
private string _bar;
public Foo
{
get;
set {
if (_foo != value)
{
_foo = value;
Bar = _foo.Substring(3, 5);
}
}
}
public Bar
{
get;
set {
if (_bar != value)
{
_bar = value;
Foo = "XXX" + _bar;
}
}
}
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; }
}
}
Is there a way to force usage of properties instead of private backing fields?
For example:
//field
private string str;
// property
public string Str
{
get { return this.str; }
set { this.str = value; DoSomething(); }
}
Both members need to have read rights however only property should have write rights. How to achive that?
EDIT: I was talking about access rights inside the class. Not from outside.
I'm assuming the reason that you don't want to be able to write directly to str within the class is because DoSomething is tightly coupled to its value changing. So to deal with that, use separation of concerns principles: create an internal class and make it solely responsible for ensuring that coupling is maintained:
internal class StrDoSomethingCoupler
{
private readonly Action _doSomething;
private string str;
public StrDoSomethingCoupler(Action doSomething)
{
_doSomething = doSomething;
}
public string Str
{
get { return _str; }
set { _str = value; _doSomething(); }
}
}
public class SomeClass
{
private readonly StrDoSomethingCoupler _coupler =
new StrDoSomethingCoupler(DoSomething);
...
public string Str
{
get { return _couple.Str; }
set { _coupler.Str = value; }
}
}
Although not clear this is a good question. Let me rephrase it.
Class A
{
//field
private string _str;
// member
public string Str
{
get { return _str; }
set { _str = value; DoSomething(); }
}
public void SomeMethod()
{
_str = "Dont access like this";
Str= "Should access only like this";
}
}
Sadly the answer is No, you cannot restrict the access of _str within Class A. Its only a coding practice you should follow, no inbuilt language feature that supports it. Reference - Blocking access to private member variables? Force use of public properties?
There is a problem that I can see in the sample code. You are doing two things within the setter of Str.
i.e. set { _str = value; DoSomething(); } is a bad practice(Although some places its unavoidable, like NotifyPropertyChanged() in wpf).
So don't do that, better change that logic by separating DoSomething() from Str.set. Something like
Class A
{
//field
private string _str;
// member
public string Str
{
get { return _str; }
private set { _str = value; }
}
private void DoSomething()
{
..
..
}
public void UpdateStrAndDoSomething(string strValue)
{
Str = strValue;
DoSomething();
}
}
private string _str;
public string Str
{
get { return _str; }
private set { _str = value; DoSomething();
}
public class Foo
{
public Foo(){ }
//One of many properties
//set up in the same way
private String _name;
public String Name
{
get { return _name; }
set {
_name = value;
//code that is important to run
//only after the objects initial creation
}
}
private int _id;
public int ID
{
get { return _id; }
set {
_id = value;
//code that is important to run
//only after the objects initial creation
}
}
public void Win()
{
//clean up method that wouldn't be needed
//if I used optional parameters because
//i would be able to set _name (and all the
//other private properties directly without
//using the public Set
}
}
How do I call a method automatically after this kind of object creation in c#
Foo ko = new Foo() {
ID = 4,
Name = "Chair"
};
ko.Win(); // <-- Want this to be called automatically inside the class
There is no method that automatically called after some random set of properties is set (Which is what initialization is translated to...)
var foo = new Foo { Name = "bar" };
Is actually shortcut to:
var foo = new Foo();
foo.Name = "bar";
When written in second form one would not expect any magical method to be called after foo.Name assignment.
You options:
if you have some information that need to be set on property change - just make it a property and write code in set part of it.
if you must have particular set of properties configured before object is considered "created" constructor arguments is one reasonable way to enforce it.
you can also implement builder pattern that allow you to delay final construction (or use some other factory method that forces setting parameters before final object creation.
Sample of code with builder pattern:
var foo = new FooBuilder { Name = "bar" }
.Build();
add the Win() to the constructor. Call/put inside the constructor.
public Foo(string value, string value2) {
Value = value;
Value2 = valu2e;
Win();
}
This is the constructor. Set it manually.
Well if you are always setting ID and the Name how about this?
private string _Name;
public string Name
{
get { return _Name; }
set {
_Name = value;
this.Win();
}
}
Win function will always called after you set a value on the name or you can do this for ID that's your choice!
Not the most scalable solution but why not try this:
public class Foo
{
public int ID { get; set; }
public String Name { get; set; }
public Foo()
{
}
public Foo( int id )
{
// Win()
ID = id;
// Win()
}
Public Foo( string name )
{
// Win()
Name = name;
// Win()
}
public Foo( int id, string name )
{
// Win()
ID = id;
Name = name;
// Win()
}
public void Win()
{
//Do Stuff that would go into the constructor
//if I wanted to use optional parameters
//but I don't
}
}
You can call Win before or after setting the properties.
One of my (senior) coworkers does something really strange in his code.
Instead of checking a variable for null, he checks for the type. And because
null is FooType
actually returns false, this works.
public class Foo
{
private string _bar = null;
public string Bar
{
get
{
// strange way to check for null
return (_bar is string) ? _bar : "";
}
set { _bar = value; }
}
}
I think this is bad coding and Resharper seems to agree with me. Is there any reason to write the check this way?
Is this a valid way to check the variable? Or can this be considered bad style or maybe even harmful in some special cases?
I don't want to confront him unless I am sure that this actually does not make sense.
This is not a good way. A better way would be to just:
return _bar ?? string.Empty;
Is it clear when you read your colleagues code that he is looking for nulls? No, then it isn't a good choice. Probably what the "is" operator will do first is just check for null and then return false. So it becomes much cleaner to just do that yourself. Or just use the null-coalescing operator
I think this code is completely confusing and would never use it. _bar is declared as a string so this type check is just begging people to not understand the code.
Yeah that's a little odd. Why not just write:
return _bar ?? "" ;
When I need to do something like this, I have a little class to handle these details:
public class DefaultableValue<T>
{
private T m_Value = default(T);
public T Value
{
get
{
if (IsInvalidPredicate(m_Value))
{
m_Value = IfDefaultValueFunc();
}
return m_Value;
}
}
private Predicate<T> IsInvalidPredicate { get; set; }
private Func<T> IfDefaultValueFunc { get; set; }
public static implicit operator T(DefaultableValue<T> property)
{
return property.Value;
}
public DefaultableValue(Predicate<T> isInvalidPredicate,Func<T> ifDefaultFunc)
: this(default(T), isInvalidPredicate, ifDefaultFunc)
{
}
public DefaultableValue(T initValue, Predicate<T> isInvalidPredicate, Func<T> ifDefaultFunc)
{
this.m_Value = initValue;
this.IsInvalidPredicate = isInvalidPredicate;
this.IfDefaultValueFunc = ifDefaultFunc;
}
}
Then my class looks like
class Test
{
DefaultableValue<string> AString { get; set; }
public Test(string initialValue)
{
this.AString = new DefaultableValue<string>(initialValue,
(value) => string.IsNullOrWhiteSpace(value),
() => string.Empty);
}
}
....
var test = new Test(null);
var someString = test.AString; // = "" not null
if the above public property was declared to return object instead of string, the above could make sense. However, because it is returning string, that type of check does not make sense. If you want to return an empty string that you could do something like this:
public class Foo
{
private string _bar = null;
public string Bar
{
get
{
return (String.IsNullOrWhitespace(_bar)) ? "": _bar;
}
set { _bar = 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.