How to make a property set itself using {} instead of ;? - c#

Here is an interesting tidbit where I could not really find on the interwebs. The idea is that if you have a property such as int a { get; set; } it could set itself.
How do you make the property set itself with int a { get { } set { } }?
What is happening inside of set;?
Here is what I tried to do:
public string Symbol { get { return Symbol; } set { Symbol = value; NotifyPropertyChangedEvent("Symbol"); } }
But it obviously creates a Stack Overflow because it is essentially calling itself over and over.
And I don't want to create 10-20 private variables to work along side of my properties, I want to know what is happening in set;.
Thank you.

set; just creates a private variable that you can't see. You'll need those 10-20 private variables, sorry.

You have to create private variables.
Unfortunately, that's the only way in the specific circumstance you have here.

If you need custom logic, you'll need to provide the backing field yourself:
private string symbol;
public string Symbol
{
get { return symbol; }
set { symbol = value; NotifyPropertyChangedEvent("Symbol"); }
}
And I don't want to create 10-20 private variables to work along side of my properties, I want to know what is happening in set;.
With an automaticaly property (ie: public string Symbol { get; set; }), the compiler creates the backing field automatically. However, there is no way to introduce logic (ie: raise your event) without managing the backing field(s) yourself.

It generates a backing field for you when it gets compiled. You cannot access it via intellisense because it has not been created yet. It is equivalent to the following where '_a' has not been generated yet.
private int _a;
public int a
{
get { return _a; }
set { _a = value; }
}
You could, however, simply set the property itself from inside of your class.
public int a { get; set; }
a = ...;
Additionally, you can set modifiers on the get and set if you only want to be able to set it internally;
public int a { get; private set; }

Related

How can I update a database value when I change the value of a property?

I have this code:
public static class Settings
{
public static int Trk5 { get; set; }
}
Settings.Trk5 = 2;
db2.Update(new Setting { "Trk5", Value = val.ToString() });
Would it be a good idea to somehow combine the updating of the database with the setting of the variable and if so how could I do that?
Can I combine the db2.Update into the set; somehow?
You could let the property save itself in its setter (like #Alsein proposed). You would need to convert your auto-property to a full property for that.
Perhaps this might work:
public static class Settings
{
private static int trk5;
public static int Trk5
{
get { return trk5; }
set
{
if (trk5 != value)
{
trk5 = value;
db2.Update(new Setting { "Trk5", Value = value.ToString() });
}
}
}
}
Settings.Trk5 = 2;
However, I doubt if your db2.Update call will work this way. You are creating a new Setting instance there, but you did not specify the property name for the "Trk5" value...
You need to call the Update method within the property.
If you want it to be automatically applied to every single properties, consider the following solutions:
Make a proxy that raises the changing event dynamically at runtime.
Inserting the notification statically at build time.

Why is it not allowed to have only one accessor with a body instead of two?

Assume I had this property:
public int Money
{
get;
set{
Money = value;
}
}
This won't compile, saying that the get accessor must have a body because it is not marked abstract, extern or partial. If I add a body to it and return the Money property like so:
public int Money
{
get{
return Money;
}
set{
Money = value;
}
}
.. I'll have an infinite loop on my hands and my program will throw a stack overflow exception.
So my question ultimately boils down to: Is there a way I can keep the get/set accessors, return the current value in get without creating an infinite loop, and still have a body for the set accessor?
Either use:
public int Money { get; set; }
or if you really need to have a body for accessors, you need to use a backing field:
private int _money;
public int Money
{
get { return _money; }
set { _money = value; }
}
However, the latter is only used if you need to perform some additional logic (e.g. raise an event) when getter or setter is used.
Also, the latter is more or less what the compiler generates for you automatically and it can ensure that the backing field is used consistently.
If you provide only one body, it becomes hard to define how should it behave: after all you don't have access to the generated backing field in your code so the whole idea doesn't make sense.
If you declare a body for one of the accessors, you're not dealing with an auto-implemented property anymore and need to implement the other accessor as well.
This is an auto-implemented property:
public int Foo { get; set; }
Which will generate a backing field when compiled. It will represent something like this in IL:
private int BackingField_Foo;
public int Foo
{
get { return BackingField_Foo; }
set { BackingField_Foo = value; }
}
In the case of an auto-implemented property, the compiler generates the field, so it knows where to read and write the value - but you can't access it.
Now if you implement one of the accessors yourself, to write to a self-defined field yourself, it's not an auto-implemented property anymore, so you'll have to implement the other accessor as well (as long as you declare it; you can create a regular read- or write-only property just fine).
Your current code throws StackOverflowExceptions because the accessors access themselves, ad infinitum.
See also Correct use of C# properties.
You can do the one of the following:
// 1. a public variable
public int Money;
// 2. an auto-implemented, or implicit property (very much like the above)
public int Money { get; set; }
// 3. An explicit property declaration with a private variable
private int _money;
public int Money {
get {return _money;}
set {
_money = value;
// possibly do something else here
}
}

what the best way to declare a property

I'm switching from Objective-C to C# to start using the Unity engine. So I'm trying to soak in all the C# differences. Obj-C has the #synthesize that auto creates the getters and setters. To to be honest they're sort of new to me. In Obj-C I'd often do:
#synthesize myProperty = _myProperty;
Then use the _myProperty in the local class code and access that property outside of this class using myProperty. Or more accurately classInstance.myProperty.
Also in Obj-C you can declare a property to be readonly and not worry about accidentally changing it's value outside the class.
In C# I'm trying to write proper object oriented code and I struggle with this. I'm a C coder at heart and am comfortable having access to everything everywhere, which I know is bad and unnecessary. I also don't want to expose tons of properties to the GameObject Inspector. I prefer to do as much programmatically as possible.
So what is the best way to declare properties so I can access them from another class but also so they are not exposed in the Inspector? Here are some possibilities that I've encountered and used:
// 1. public static - public without being exposed in inspector
public static int myProperty;
// 2. the public _text doesn't appear in the inspector but the text one does.
public string _text;
public string text {
get { return _text; }
set {
_text = value;
}
}
// 3. private _underscore version with no setter - does removing the set make it read only?
private float _current;
public float current {
get { return _current; }
}
// 4. creating my own getter function
private int myValue;
...
int GetMyValue() {
return myValue;
}
Also.. I read somewhere that in .NET you shouldn't use underscores in property names. I don't really know what the underscore version of the property does or represents. I thought in Obj-C it effected the scope, but don't really know.
Am I even correct in calling variables properties?
Someone suggested prop tab tab which produces this:
public object MyProperty {
get;
set;
}
Unfortunately that doesn't really answer my question about read only. Is an int or string even an object? It's not in Obj-C.
Public variables (not fields) are shown in the Unity inspector. If you want a public variable to be hidden, you can preface it with NonSerialized, like this:
[System.NonSerialized]
public bool m_HideWhenInactive = false;
You can also avoid this problem entirely by making it a property. No properties are shown in the inspector:
public bool m_HideWhenInactive { get; set; }
As a fun bonus (not your question, I know), you can have a property that's world-read, private-write:
public bool m_HideWhenInactive { get; private set; }
And finally, if you DO want a variable to be serialized and stored in a prefab, but you don't want the designers editing it (if you intend to write a custom editor class), there's a different annotation for that:
[HideInInspector]
public bool m_HideWhenInactive = false;
Static fields are never shown in the inspector.
The NonSerialized and HideInspector attributes are the two options you must consider to hide members of the class from the Unity inspector. NonSerialized is not specific to Unity, HideInspector is specific to Unity. Unity looks for both of these attribute in your compiled code to determine what gets exposed in the inspector.
If you want a publicly read only property you declare it like so...
[System.NonSerialized]
private string _text;
/// <summary>
/// Gets the Text
/// </summary>
/// <remarks>May be set within this class or derived classes</remarks>
public string Text {
get { return _text; }
protected set {
_text = value;
}
}
You seem to be having issues with the meaning of access modifiers...
See this page...
https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx
Briefly...
public = accessible from anywhere, do not declare backing variables on properties as public, otherwise people can simply skip your property accessor.
protected = accessible within your class and from classes inheriting the class
internal = accessible within the same assembly
protected internal = accessible within the same assembly and from
classes inheriting the class
private = accessible only within your class
You can do away with backing variables simply by declaring
/// <summary>
/// Gets or sets the Text
/// </summary>
public string Text { get; set; }
/// <summary>
/// Gets the current
/// </summary>
public float Current { get; protected set; }
Since the advent of auto-implemented variables, there are no technical reasons for creating properties with backing variables unless you have additional logic you would like executed on the get and/or set.
e.g you wanted to create Observable entities that raise an event when a property is changed...
private int _id;
public int ID
{
get
{
return _id;
}
set
{
if (_id != value)
{
OnIDChanging(value);
ReportPropertyChanging("ID");
_id = StructuralObject.SetValidValue(value);
ReportPropertyChanged("ID");
OnIDChanged();
}
}
}
In terms of coding standards, there are plenty of them on the net. I'd recommend IDesign's...
http://www.idesign.net/downloads/getdownload/1985
You'll notice I changed the casing on the code you posted, the casing I've used adhere's to IDesign's naming guidelines
The correct way to create properties really depends on what it is you're trying to accomplish. If you're only wanting to have a property be created for further use you can create the shorthand way:
public object MyProperty { get; set; }
If more functionality is required, you can add additional functionality, such as:
private int _myInt;
public int MyInt {
get { return this._name; }
set {
if (this._name == 1) {
this._name = value;
} else {
this._name = 0;
}
}
}
The answer of your question is it simply depends on what it is you're looking to achieve and both ways are accepted.
The use of getter and setter methods, such as those found in Java, are frowned upon in C#.
To answer your other question, String is an object in C#. int is a primitive type.
Here's a quick summary of your problems.
There is a so called snippet in C# that allows you to quickly generate code. The quick shortcut for it is typing prop and then pressing tab which would generate a code to something like this.
public int MyProperty { get; set; }
Now if you're going to create fields, and you dont want to expose that to an instance. You should make it private.
Example
private int myVar; // private is not exposed on instances only public properties are
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
Now for static fields, static fields/properties are type accessible. So to hide them, you only have to make them private
Example
private static bool myProp; // can't be accessed on the Program Type
public static bool MyProp { get; set; } // can be accessed on the Program Type
class MyClass
{
public MyClass()
{
Program.MyProp = true;
Program.myProp= true; // wont build
}
}
If you want it to be readonly and prevent modification, you can do it like this.
public int MyProperty { get; private set; } // can get but not set
private int myVar;
public int MyProperty
{
get { return myVar; } // same as the top but with a field
}
For a deeper and better understanding, please do read about What are Access Modifiers in C#?
Property patterns in the context of the Unity engine tend to differ slightly to the 'norm' of C# because of you are often interested in making them tweakable data in the editor. This means serialization.
Unity cannot serialize properties
Unity can serialize fields of primitive types and types inheriting from UnityEngine.Object are serialized references
Unity can serialize list and arrays of the types mentioned above as well
Serialized fields on MonoBehaviours are exposed in the editor and are editable
public fields are serialized by default and private fields if they are marked with the [SerializeField] attribute.
Unity also serializes fields on classes marked with [System.Serializable] if the class is a field on a MonoBehavior
For a more in-depth discussion see: https://blogs.unity3d.com/2014/06/24/serialization-in-unity/
The following pattern is common, the backing field can be set by the developer, without needing to recompile, and cannot be changed by external code at run-time.
[SerializeField]
private int editableInEditor;
public int NotEditableInEditor
{
get { return editableInEditor; }
}
So is this pattern, a lazy-getter.
private DerivedMonoBehaviour component;
public DerivedMonoBehaviour Component
{
get
{
if(component == null)
{
// Note: Using the null-coalescing operator ??
// is inadvisable when dealing with UnityEngine.Object
// references.
// See: https://blogs.unity3d.com/2014/05/16/custom-operator-should-we-keep-it/
component = GetComponent<DerivedMonoBehaviour>();
}
return component;
}
}

What's the difference between a property with a private setter and a property with no setter?

If I want a read-only property, I write it like:
public int MyProperty { get { //Code goes here } }
However, the Microsoft example (and a few other examples I've seen) are written like:
public int MyProperty { get; private set; }
Is there any difference between these two, and should I start writing properties like this?
As you can see in your second sample, you can leave out the implementation for a property. .NET will then automatically create a local variable for the property and implement simple getting and setting.
public int MyProperty { get; private set; }
is actually equivalent to
private int _myProperty;
public int MyProperty {
get { return _myProperty; }
private set { _myProperty = value; }
}
Writing
public int MyProperty { get; }
does not work at all, as automatic properties need to implement a getter and a setter, while
public int MyProperty { get; private set; }
leaves you with a property that may return any int, but can only be changed within the current class.
public int MyProperty { get { ... } }
creates a read-only property.
Question is: what do you need? If you already have a member variable that's used within your class and you only want to return the current value using a property, you're perfectly fine with
public int MyProperty { get { return ...; }}
However, if you want a read-only property, which you need to set within your code (but not from other classes) without explicitly declaring a member variable, you have to go with the private set approach.
With private setter you can only assign property value inside of instance when property is without setter you can't set its value anywhere.
If you don't use an explicit member assignment in the property, you'll have to declare a private set at least in order to be able to set a value to this property. Otherwise, you'll get a warning at compile-time saying that your property cannot be assigned.
If you use an explicit member, you'll be able to assign a value to this member directly, without needing to add a private set:
private int member ;
public int MyProperty {
get { return member; }
}
// ...
member = 2;
int anotherVariable = MyProperty; // anotherVariable == 2
public int MyProperty
{
get
{
// Your own logic, like lazy loading
return _myProperty ?? (_myProperty = GetMyProperty());
}
}
A property with only a getter is very useful if you need your own logic behind the access of that property, in particular when you need the property to be lazy loaded.
public int MyProperty { get; private set; }
A property with a private setter is useful if you need the property not te be changed from the outside, but still maintained from within the class.
In both cases, you can have a backing data field for the actual value, but in the former, you'll have to maintain that yourself, and in the latter, it is maintained for you by the generated code.
There is a difference when you access the object with reflection.
public class Foo
{
public string Bar { get; private set; }
}
// .....
internal static void Main()
{
Foo foo = new Foo();
foo.GetType().GetProperty("Bar").SetValue(foo, "private?", null);
Console.WriteLine(foo.Bar);
}

null exception with lists in c#

hey i am trying to work with a generic list in C# and for some reason after allocating memory for the list i am getting unhandeledNullException.
//edit
i found out what was my problem i did not use the properties currectly.
if lets say GeoInfo is a private member of my class, how do i do properties to it,
i tried :
private List<GeoInfo> GEOINFOS { get; set; } // edit i forgot to change it back
// but i want to have my geoinfos private and my properties public
thanks in advance for your help
You've made the properties private. If you want them to be public try:
public List<GeoInfo> GeoInfos { get; set; }
The auto-implemented value that is stored locally in the object will be private; but the properties themselves are public.
Because what you are declaring there are the property accessors.
If you want to write everything explicitly, you could do it the old pre 3.0 way
private List<GeoInfo> geoInfos = new List<GeoInfo>;
public List<GeoInfo> GeoInfos {
get { return geoInfos; }
set { geoInfos = value; }
}
This still relies on geoInfos being initialized somewhere (like the constructor) -- or nullPointerException will return.
You could do lazy-evaluation on it right in the getter:
private List<GeoInfo> geoInfos = new List<GeoInfo>;
public List<GeoInfo> GeoInfos {
get { if (geoInfos == null) {
geoInfos = new List<GeoInfo>;
}
return geoInfos;
}
set { geoInfos = value; }
}
This ensures that you don't have to specify a call in the constructor, and you don't have to worry about the execution sequence setting the element explicitly prior to getting it.
But if you use the auto-generated-properties, you will have to explicitly set the reference at some point. AS suggested elsewhere, the best bet is the constructor.
If you want a property to be private, use
private List<GeoInfo> GEOINFOS { get; set; }
However, there's not a lot of reason to use an auto property for a private member variable (and don't forget to initialize that list as well). If you want validation fine, but you're just using that property as a private variable.
Your null reference issue probably comes from not initializing the underlying property variable. That does not get done automatically, so
public MyClass()
{
GEOINFOS = new List<GeoInfo>();
}
One more thing: your naming convension for a property is odd for C#. How about keeping things consistent and sing GeoInfos?

Categories

Resources