This might be a trivial question but I got really confused on this. I have a property with some logic in it.
private SomeObject _someProperty;
public SomeObject SomeProperty
{
get
{
Some checking here,
return _someProperty;
}
set
{
_someProperty = value;
}
}
Now what will happen when I am going to assign something to this property.
SomeProperty = new SomeClass();
What I was thinking here that get will be called here. It words it can be said like get SomeProperty and set that property. But what I have observed is that get is not called. Only setter is called (correct me if I am wrong here). I want to know if get is not called here what is its reason.
In simpler way to think about it.
GET: When something somewhere wants to GET value from here.
SET: When something somewhere wants to SET value here.
So, getters and setters answer to question from outside perspective. When you want to write value, SET is called. When you want to know current value, GET is called.
Properties are really just syntactic sugar for get/set methods. As the C# Programming Guide says:
A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Properties can be used as if they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily and still helps promote the safety and flexibility of methods.
So your example really translates to something like:
private SomeObject _someProperty;
public SomeObject get_SomeProperty()
{
// Some checking here,
return _someProperty;
}
public void set_SomeProperty(SomeObject value)
{
_someProperty = value;
}
With the assignment becoming
set_SomeProperty(new SomeClass());
When thought of this way, it's clear that the getter is not called when you assign the property.
No, a property's getter is not called when setting the property, as can be easily demonstrated :
static class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
foo.Number = 7;
}
}
public class Foo
{
private int number;
public int Number
{
get
{
Console.WriteLine("In getter");
return this.number;
}
set
{
Console.WriteLine("In setter");
this.number = value;
}
}
}
Output:
In setter
No, get is called when you are reading the value of the property, set is called when you are assigning a value to the property.
What I was thinking here that get will be called here
Why? You are clear - you SET. And SET does not do anything in GET. Ergo, get is never called.
This IS the correct behaviour of mutator methods, you dont Read the Value from accessor
You don't need value of SomeProperty in this expression. If you wrote something like SomeProperty = SomeProperty + 1; then you will need a value of SomeProperty, and get will be called.
Actually
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be used
as if they are public data members, but they are actually special
methods called accessors.
as it is said in msdn.
So consider it as a wrapper for something like this:
private SomeObject _someProperty;
public SomeObject getSomeProperty()
{
//Some checking here,
return _someProperty;
}
public void setSomeProperty(SomeObject value)
{
_someProperty = value;
}
It should be clear now unless you have the same question about setting the fields.
Related
There's so many ways to write getters and setters that it confuses me.
Are this two doing the same thing?
private List<MyClass> myPrivateList;
//Method 1
public List<MyClass> MyPublicList{ get => myPrivateList; private set { } }
//Method 2
public List<MyClass> MyPublicList=> myPrivateList;
And if so, does this allows me to see this propierty from another class while not allowing me to edit it?
Thank you :).
Either way, someone will be able to edit the list, as when anyone gets myListReference = instance.MyPublicList;, they get a reference to myPrivateList.
If you want to get a shallow copy of myPrivateList, you would want to do get=>new List<MyClass>(myPrivateList);. That would allow the removal or addition of items in myListReference without affecting myPrivateList.
But even then, that is merely a shallow copy, so if the items of myListReference are edited, the same items will be edited in myPrivateList. To prevent that, you would need to do a deep copy.
Exactly how to go about that deep copy would depend on the exact nature of MyClass but you might learn more information from this question, using a class that defines a copy constructor.
The getters in method 1 and method 2 are equivalent. Method 1 also exposes a setter that does nothing, which is not quite the same as method 2. That would lead to confusion, because from within the declaring class it lets you write things like
this.MyPublicList = new List<MyClass>();
While that line looks like it should do something, the body of the setter is empty, so it doesn't do anything. I think what you're going for would be to just not specify the setter at all:
public List<MyClass> MyPublicList { get => myPrivateList; }
If you do want the setter to be usable privately, then you'd need to define the body:
public List<MyClass> MyPublicList { get => myPrivateList; private set => myPrivateList = value; }
private MyType _member;
public MyType GetMember() { return _member; }
public void SetMember(MyType value) { _member = value };
This is the basic way to protect a private member with public getter and setter methods (a property). Regardless of how you define a property, this is the C# equivalent of what will be created in MSIL. That's also why you will have the value keyword available in the setter. Every other method is merely syntactic sugar.
The Options are:
// Option 1
public MyType Member { get; set; }
// Option 2
private MyType _member;
public MyType Member
{
get
{
return _member;
}
set
{
_member = value;
}
}
// Option 3
public MyType Member
{
get => _member;
set => _member = value;
}
// Option 4
public MyType Member => _member; //Only a getter, yet even shorter.
What you can do, is not define a setter, this means you can't do an assignment with the property outside like Member = new MyType(). However, you are still able to access any methods from the outside, that in turn change the value of the underlying data-structure like in Member.Clear(). Like #Ruzihm pointed out in his excellent answer, you would have to do object-Copying to provide an "uninteractive" copy, that provides "full" protection of the original.
I have a boolean variable, I want every change to its value to invoke a piece of code.
my current solution is the following:
bool _manualControl;
bool manualControl {
get {
return _manualControl;
}
set {
this._manualControl = value;
GlobalEventManager.ManualControlEvent?.Invoke(value);
}
}
this solution has two problems:
the value of "_manualControl" can be changed internally without invoking my piece of code, I want to prevent that.
I would prefer to avoid using two variables to get the desired behavior.
Is there any way to achieve what I want while avoiding these two specified issues?
You can set the property to be public and have a private backing field that can only be modified from within the class, which you have control of.
Or you could use an Aspect Oriented Programming framework like PostSharp, which would allow you to use an auto property and annotate it with the behaviour you desire. This would remove the need for you to have a backing field.
To me this sounds a bit like you want to solve an architectural problem, aka code smell. Why is it that you fear your field might be set outside your setter? Is it a particularly large class that a lot of people are chaning without really knowing what it is doing?
Why even have code in the setter? Like you could just redesign your code to have a method do what your setter code does and introduce that into your code flow / process.
And have a Unit Test validate your desired behavior.
If you want to:
ensure that the setter code always executes when a new value is assigned (inside and outside of the class)
avoid having two members in the class, that represent a single value
Then this can be approached by wrapping the value within a struct like one below:
struct Intercepted<T>
{
private readonly Action<T> _onChange;
private T _value;
public Intercepted(Action<T> onChange, T initialValue = default(T))
{
_onChange = onChange;
_value = initialValue;
}
public T Value
{
get
{
return _value;
}
set
{
_value = value;
_onChange?.Invoke(value);
}
}
}
In the class, ManualControl can now be represented with a single member, of type Intercepted<bool>:
public Intercepted<bool> ManualControl { get; } = new ManualControl(
onChange: newValue => {
GlobalEventManager.ManualControlEvent?.Invoke(newValue);
}
);
The value can be accessed like this:
// from within the class
if (ManualControl.Value) { ... }
// from outside
myObj.ManualControl.Value = true;
Now there is no way to change the value without triggering the setter code, both inside and outside the class.
Can someone tell me, what is the porpose of using a public property for a private class member but not implementing anything in the set and get part? I know that it could be just for examples and that later on you can implement something but I don't know if there is any meaning using it like that
I am going to assume you know there is a private field generated by the C# compiler as the field backing up this property. It is syntactic sugar. I am also going to assume you know this is an auto-implemented property. So what is the point of a property if it public with no logic in the get or set. In other words, any class can access it and set its value. So why choose this property over a public field?
Purpose of it is:
Today the get and set is empty but it may need code in the future. To avoid breaking a contract in the future, you use an empty get and set.
Most .NET databinding can be done against properties but not fields. So although it is empty, it still serves a far greater purpose.
The get and set can have access modifiers. For example, you can say set is private but get is public.
A field cannot be used in interfaces but properties can.
This is an "auto-implemented" property in C#. In effect, the property acts as a full property, i.e.:
This:
public int Number { get; set; }
Is equivalent to:
private int _number;
public int Number
{
get
{
return this._number;
}
set
{
this._number = value;
}
}
This prevents you from having to type out the full property declaration. This is useful when you don't have any additional logic in the getter and/or setter.
If you're creating simple data mapping and transfer classes, auto-implementing properties can make the class definition far more concise.
When you see
public int Count { get; set; }
as a member of a class, that is not nothing. You're just deferring to the default implementation of auto-properties. It's roughly,
private int _count;
public int get__Count()
{
return _count;
}
public void set__Count(int value)
{
_count = value;
}
You just have syntactic sugar in C# to use these methods roughly like a field, i.e.
instanceOfObject.Count = 42; // Not a field access, but behind the scenes a method call.
The C# "readonly" keyword is a modifier that when a field declaration includes it, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
Now suppose I do want this "assign value once" constraint, but I would rather allow the assignment be done outside of constructors, a lazy/late evaluation/initialization maybe.
How could I do that? and is it possible to do it in a nice way, for example, is it possible to write some attribute to describe this?
If I understand your question correctly, it sounds like you just want to set a field's value once (the first time), and not allow it to be set after that. If that is so, then all the previous posts about using Lazy (and related) may be useful. But if you don't want to use those suggestions, perhaps you can do something like this:
public class SetOnce<T>
{
private T mySetOnceField;
private bool isSet;
// used to determine if the value for
// this SetOnce object has already been set.
public bool IsSet
{
get { return isSet; }
}
// return true if this is the initial set,
// return false if this is after the initial set.
// alternatively, you could make it be a void method
// which would throw an exception upon any invocation after the first.
public bool SetValue(T value)
{
// or you can make thread-safe with a lock..
if (IsSet)
{
return false; // or throw exception.
}
else
{
mySetOnceField = value;
return isSet = true;
}
}
public T GetValue()
{
// returns default value of T if not set.
// Or, check if not IsSet, throw exception.
return mySetOnceField;
}
} // end SetOnce
public class MyClass
{
private SetOnce<int> myReadonlyField = new SetOnce<int>();
public void DoSomething(int number)
{
// say this is where u want to FIRST set ur 'field'...
// u could check if it's been set before by it's return value (or catching the exception).
if (myReadOnlyField.SetValue(number))
{
// we just now initialized it for the first time...
// u could use the value: int myNumber = myReadOnlyField.GetValue();
}
else
{
// field has already been set before...
}
} // end DoSomething
} // end MyClass
Now suppose I do want this "assign value once" constraint, but I would rather allow the assignment be done outside of constructors
Note that lazy initialization is complicated, so for all of these answers you should be careful if you have multiple threads trying to access your object.
If you want to do this inside the class
You can use the C# 4.0 built-in lazy initialization features:
http://msdn.microsoft.com/en-us/library/dd997286.aspx
http://msdn.microsoft.com/en-us/library/dd642331.aspx
http://sankarsan.wordpress.com/2009/10/04/laziness-in-c-4-0-lazyt/
Or for older versions of C#, just supply a get method, and check if you're already initialized by using a backing field:
public string SomeValue
{
get
{
// Note: Not thread safe...
if(someValue == null)
{
someValue = InitializeSomeValue(); // Todo: Implement
}
return someValue;
}
}
If you want to do this outside the class
You want Popsicle Immutability:
http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx
http://msdn.microsoft.com/en-us/library/ms750509.aspx
http://csharpindepth.com/Talks.aspx (search for "popsicle immutability" and you'll find a video)
Basically:
You make the whole class writable, but add a Freeze method.
Once this freeze method is called, if users try to call setters or mutator methods on your class, you throw a ModifyFrozenObjectException.
You probably want a way for external classes to determine if your class IsFrozen.
BTW, I made up these names just now. My selections are admittedly poor, but there is no generically followed convention for this yet.
For now I'd recommend you create an IFreezable interface, and possibly related exceptions, so you don't have to depend on the WPF implementation. Something like:
public interface IFreezable
{
void Freeze();
bool IsFrozen { get; }
}
You can use the Lazy<T> class:
private readonly Lazy<Foo> _foo = new Lazy<Foo>(GetFoo);
public Foo Foo
{
get { return _foo.Value; }
}
private static Foo GetFoo()
{
// somehow create a Foo...
}
GetFoo will only be called the first time you call the Foo property.
This is know as the "once" feature in Eiffel. It is a major oversight in C#. The new Lazy type is a poor substitute since it is not interchangeable with its non-lazy version but instead requires you to access the contained value through its Value property. Consequently, I rarely use it. Noise is one of the biggest problems with C# code. Ideally, one wants something like this...
public once Type PropertyName { get { /* generate and return value */ } }
as oppose to the current best practice...
Type _PropertyName; //where type is a class or nullable structure
public Type PropertyName
{
get
{
if (_PropertyName == null)
_PropertyName = /* generate and return value */
return _PropertyName
}
}
I have the following property
public MyType MyProperty {get;set;}
I want to change this property so that if the value is null, it'll populate the value first, and then return it... but without using a private member variable.
For instance, if I was doing this:
public MyType MyProperty
{
get
{
if (_myProperty != null)
return _myProperty
else
_myProperty = XYZ;
return _myProperty;
}
set
{
_myProperty = value;
}
}
is this possible? Or do I need the member variable to get it done?
You need a member variable and a full property declaration. Automatically implemented properties are only applicable if they're trivial wrappers around a field, with no logic involved. You can simplify your getter code slightly, btw:
get
{
if (_myProperty == null)
{
_myProperty = XYZ;
}
return _myProperty;
}
(Note that none of this is thread-safe without extra locking, but I assume that's okay.)
By the way, you already have a private member variable if you're using automatically implemented properties - it's just that the compiler's generating it for you.
return _myProperty?? (_myProperty = XYZ);
The best thing you can do is to give it a value in the constructor. I know that this way you lose the "lazy loading", but you can't have auto properties and lazy loading at the same time.
Your code:
public MyType MyProperty {get;set;}
refer to "Automatic Properties", that are just "syntactic sugar", as you can check out here.
The compiler generates the field for
the property and also generates the
code in the get set to point to the
field.
internal class ClassName
{
// Fields
[CompilerGenerated]
private MyType <Property>k__BackingField;
// Properties
public MyType MyProperty
{
[CompilerGenerated]
get
{
return this.<Property>k__BackingField;
}
[CompilerGenerated]
set
{
this.<Property>k__BackingField = value;
}
}
}
So, your code will always be backed by a compiler generated field.
You need the member variable to get it done:
public class MyClass
{
MyType _myProperty = null;
public MyType MyProperty
{
get
{
if(_myProperty == null)
_myProperty = XYZ;
return _myProperty;
}
}
}
You're going to need a private variable to implement this because you have logic in your getter/setters.
If you wish to do any embellishment on the getting or setting behavior of a property, then you will lose the compiler-generated storage location, so you'll have to store the value somewhere yourself. A private member variable makes the most sense, most of the time.
I propose to consider usage of Lazy initialization.
It will not help you to avoid member variable so sorry for this, but that code will help you to avoid memory reservation for member variable until your class will need that variable:
public class MyType
{
public MyType()
{
XYZ();
}
public void XYZ()
{
//some kind of initialization
}
}
public class TestType
{
private Lazy<MyType> _myProperty;
public MyType MyProperty
{
get { return _myProperty.Value; }//_myProperty will be null until some code will try to read it
}
}
One more thing to point or actually to remind, you'll not be able to be absolutely without member variable. Because behind the curtains .Net compiler will create that member variable instead of you. It just will not notify you about this step. But as it was mentioned by others, if you look in generated MSIL, you'll see that member variable created for you.
By "member variable" I assume you mean a variable defined within the property get. Yes, you certainly don't need a locally defined variable. The more common pattern, which saves a copule lines of code, is:
if (_myProperty == null)
_myProperty = XYZ;
return _myProperty;
If by "member variable" you mean a backing field, then yes, you do need one. Only the completely simple "pass through" field/property relationship can be implemented without explicitly creating a backing field. (And even then, it's get's created by the compiler.) To instantiate-if-null, you need to explicitly define it.
Yes it's possible. But you have to implement it yourself, not with auto properties. Your properties do not necessarily need to only work with member variables though that is the default.
Remember that properties are actually turned into Getter and Setter methods and you can do a lot of work within their scope. Though this practice is usually discouraged. Good practices states that property access ought to be quick and not block the client code for long perieds of time.
You could simply do this:
public MyType MyProperty
{
get
{
if (_myProperty != null)
return _myProperty
else
return XYZ;
}
set
{
_myProperty = value;
}
}
Only when you use a member variable.
Usually, I combine lazy loading with the implementation of IDisposable, so that any variables that need to be cleaned up can be handled in the Dispose method.
If the property is required then some checking can make it bullet proof. I tend to use something like:
public MyType MyProperty
{
get
{
if (_myProperty == null)
_myProperty == XYZ;
return _myProperty;
}
set
{
if(value == null)
throw InvalidArgumentException();
_myProperty = value;
}
}
Makes TDD simpler too.
Try this
Public Class MyClass
{
Public MyType Alfa
{
If(this._Alfa == null) this.SetAlfa();
return _Alfa;
}
private MyType _Alfa {get;set;}
private void SetAlfa()
{
//Somenthing to valorize _Alfa
}
}