Expression-Bodied Function combined with Auto Properties results in problems - c#

After finally upgrading to VS2015 and starting utilizing .NET4.6, I have been utilizing some of the syntactic sugar when I have come across old classes.
Unfortunately, this doesn't always go smooth :/ An example of this, is the following example.
I have this existing code that works.
private static string _bootstrapBundle;
public static string BootstrapBundle
{
get
{
return _bootstrapBundle;
}
}
A quick rewrite to use expression body gives me this, which works
private static string _bootstrapBundle;
public static string BootstrapBundle => _bootstrapBundle;
This can also be rewritten to use auto properties, like the following code which works
public static string BootstrapBundle { get; private set; }
If I try to take it a step further, and write the following, it doesn't work
private static string _bootstrapBundle;
public static string BootstrapBundle { get; private set; } = _bootstrapBundle;
All three examples of code compiles just fine, but when I later on try to assign a value like the following, it's only with the last piece of code that it fails to assign anything to BootstrapBundle.
BootstrapBundle = SquishIt.Framework.Bundle.Css()
.Add("/assets/stylesheets/Theme/" + theme + "/Bootstrap/bootstrap.less")
.Render("/assets/Cache/bootstrap.css");
How can this be? Are the expressions resolved differently? At different times? Am i abusing the syntax?

Let's go though the options you gave one by one and look at what each does:
private static string _bootstrapBundle;
public static string BootstrapBundle
{
get
{
return _bootstrapBundle;
}
}
I'm assuming that I don't have to explain what this does. But note that if you try to assign to BootstrapBundle, it will fail at compile time, since there is no setter. But you can work around that by assigning directly to the field.
private static string _bootstrapBundle;
public static string BootstrapBundle => _bootstrapBundle;
This is exactly the same as #1, only with more succinct syntax.
public static string BootstrapBundle { get; private set; }
Here we have an auto-property, that is a property with hidden (unspeakable) backing field. It compiles to:
private static string <BootstrapBundle>k__BackingField;
public static string BootstrapBundle
{
get
{
return <BootstrapBundle>k__BackingField;
}
private set
{
<BootstrapBundle>k__BackingField = value;
}
}
This means that setting the property now works and getting it after setting will give you the new value.
private static string _bootstrapBundle;
public static string BootstrapBundle { get; private set; } = _bootstrapBundle;
This is the same as #3, except that the hidden backing field is initialized to the value you gave:
private static string _bootstrapBundle;
private static string <BootstrapBundle>k__BackingField = _bootstrapBundle;
public static string BootstrapBundle
{
get
{
return <BootstrapBundle>k__BackingField;
}
private set
{
<BootstrapBundle>k__BackingField = value;
}
}
What this means is that there are now two fields: one hidden and one visible. The hidden field will initially be set to the value of the visible field (which is null), but after that, the two fields won't affect each other.
This means that if you set the property, and then get the property, you will get the updated value. But if you read the visible field, its value won't be updated. And vice versa: if you update the field, the value of the property won't change.

If you want the behavior to be exactly the same, you have these two options:
With expession body (like you offered, and with no other refactoring needed):
private static string _bootstrapBundle;
public static string BootstrapBundle => _bootstrapBundle;
With auto properties (like you also suggested, here you have to refactor all assignments to use the property rather than the field variable):
public static string BootstrapBundle { get; private set; }
The reason why your last example did not work, is that the field variable does not have a value when you try to assign it, where as using expression body, the getter is resolved every time you access the property, and assignment can be delayed. Put in other words, it works as readonly, and assignment of the variable has to happen inside a constructor, making the field variable useless, unless you want to use it for other methods (which would be completely unreadable and a terrible debugging experience!) :)
If you want your last example to work, you have to use a constant instead:
public static string BootstrapBundle { get; private set; } = "42";
but if you do not need the default value not much changes for you, and you might as well leave it out.

There are several ways of defining the property:
// this defines a public getter, public setter property with no backing field (there is an internal one, but not one you can access)
public static string BootstrapBundle {
get;
set;
}
// this defines a public getter, public setter property with a backing field
private static string _bootstrapBundle = "42";
public static string BootstrapBundle {
get {
return _bootstrapBundle;
}
set {
_bootstrapBundle = value;
}
}
//this defines a no setter property with a backing field
private static string _bootstrapBundle = "42";
public static string BootstrapBundle {
get {
return _bootstrapBundle;
}
}
using C#6 features:
// this sets a getter only property that returns the current value of _bootstrapBundle (equivalent to the last form in the code above)
private static string _bootstrapBundle = "42";
public static string BootstrapBundle => _bootstrapBundle;
// this sets up an auto property (no backing field) that at initialization gets the initial value of _bootstrapBundle
private static string _bootstrapBundle = "42";
public static string BootstrapBundle {get;set;} = _bootstrapBundle;
// equivalent to this:
public static string BootstrapBundle {get;set;} = "42";
Since you are setting the property in your code, it means you need a setter. If all what you wanted is a property with a backing field, you have no C#6 syntax to replace the good old return _backingField;/_backingField=value

Related

c# pass property backing value by reference, is it possible?

Following on from my earlier question: c-sharp-convert-existing-class-to-use-properties-correctly
I have a class like this:
public class TestCaseInfo
{
public string text { get; set; } = "";
public string requirement_ref { get; set; } = "";
public string given { get; set; } = "";
public string when { get; set; } = "";
public string then { get; set; } = "";
public UInt32 timeLimit { get; set; } = 0;
}
I was previously populating the structure like this:
if (!getNodeValue(testcase_node.SelectSingleNode("text"), ref testcaseInfo.text))
errStr += nodeError(testcase_node, "Missing 'text' node");
Note: that I am trying to pass it by reference. I have read a load of quetions that all basically say that you can't do this. Fair enough...
So I want to pass in the "real" value (I think its called the backing value?) instead. Something like:
if (!getNodeValue(testcase_node.SelectSingleNode("text"), ref testcaseInfo._text)) // where '_text' should be the 'backing' value.
errStr += nodeError(testcase_node, "Missing 'text' node");
But I am missing two things (probably more!):
What is the backing value called?
I assume its private? - can I make it protected and make it a friend class? (that might be C++ talk... not sure if there is the same idea in C#)?
There is no valid identifier for the backing field for that property. You could not use an auto property, and instead explicitly define the get and set methods of the property, along with your own backing field, thus giving you a valid identifier for the backing field, although it would be very poor design to expose this backing field externally.
What you should do is re-design your code such that you don't need to pass the value by reference in the first place. You should just be passing the string by value and, if the result of this function is the computation of a string, returning it. The caller can then set that string back to the property if that's what they want. That would be the more idiomatic design. (Since you also have a boolean value you'd need to pass both the string and the boolean out, of course.)
As far as you are concerned, your properties may as well not have backing fields. The backing field isn't called anything you can refer to if you didn't explicitly declare it:
private string _name;
public String Name { get { return _name; } set { _name = value; } }
If you write properties with explicit backing fields, as above, you can pass them by ref into a method.
private int _id;
public String ID { get { return int _id; } set { int _id = value; } }
public void Test()
{
Int32.TryParse("Sausage Factory", out _id);
}

Not sure how to use this class

I want to have a class where I can set and get for each note. So I parse an XML file and with each <note> attribute in the file, I set and get the Note class. This was an alternative method to the Dictionary<int,string> that I had last time.
So why did I change it? Because for the double notes, (when the times were the same), the int within the dictionary would be a duplicate key and throw an error. So now, I've made a list with my Note class.
Here's the note class:
class Note
{
public enum Notes
{
A, S, D, J, K, L,
};
public Notes CurrentNote { get; set; }
public string Time { get; set; }
public Note(Notes Note, string Time) {
this.CurrentNote = Note;
this.Time = Time;
}
}
And then in my NoteManager.cs, I'll add to the list and set the values through that. But I'm not totally sure if this will work? I've never worked with getting and setting of classes. I tried adding the Notes to the list, but the way that I get the values doesn't seem to work. It gives a weird output.
System.Linq.Enumberable+D_3a`1[Hit_Machine.Managers.Note]
Here's the NoteManager.cs Class:
class NoteManager : Game1
{
public static List<Note> Notes = new List<Note>();
public static void addNotes() {
Notes.Add(new Note(Note.Notes.A, "22.22"));
Notes.Add(new Note(Note.Notes.A, "33.33"));
Notes.Add(new Note(Note.Notes.A, "55.55"));
}
public static void getNotes(Game1 Parent)
{
Game1.myGameText = Notes.Take(5).ToString();
}
}
So what actually would be the proper way of using this method?

Looking for a short & simple example of getters/setters in C#

I am having trouble understanding the concept of getters and setters in the C# language. In languages like Objective-C, they seem an integral part of the system, but not so much in C# (as far as I can tell). I have read books and articles already, so my question is, to those of you who understand getters & setters in C#, what example would you personally use if you were teaching the concept to a complete beginner (this would include as few lines of code as possible)?
I think a bit of code will help illustrate what setters and getters are:
public class Foo
{
private string bar;
public string GetBar()
{
return bar;
}
public void SetBar(string value)
{
bar = value;
}
}
In this example we have a private member of the class that is called bar. The GetBar() and SetBar(string value) methods do exactly what they are named - one retrieves the bar member, and the other sets its value.
In C# 1.1 and later, you have properties. The basic functionality is also the same:
public class Foo
{
private string bar;
public string Bar
{
get { return bar; }
set { bar = value; }
}
}
The private member bar is not accessible outside the class, but the public Bar is, and it has two accessors: get, which returns the private member just as the GetBar() example above, and also a set, which corresponds to the SetBar(string value) method in the aforementioned example.
Starting with C# 3.0 and above, the compiler was optimized to the point that such properties do not need to be explicitly given a private member as their source. The compiler automatically generates a private member of that type and uses it as a source of a property.
public class Foo
{
public string Bar { get; set; }
}
What the code shows is an automatic property that has a private member generated by the compiler. You don't see the private member, but it is there. This also introduced a couple of other issues - mainly with access control. In C# 1.1 and 2.0, you could omit the get or set portion of a property entirely:
public class Foo
{
private string bar;
public string Bar
{
get { return bar; }
}
}
Giving you the chance to restrict how other objects interact with the Bar property of the Foo class. But from C# 3.0 to before 6.0, if you chose to use automatic properties, you would have to specify the access to the property as follows to emulate that behavior:
public class Foo
{
public string Bar { get; private set; }
}
The set accessor would still exist, but only the class itself could use it to set Bar to some value, and anyone could still get the value.
Thankfully, starting in C# 6.0, properties can be made read- or write-only again by simply omitting the property's get or set respectively (not to be confused with the readonly keyword):
public class Foo
{
// Read-only property
public string Bar { get; }
// Write-only property (less common)
public string Baz { set; }
}
In C#, Properties represent your Getters and Setters.
Here's an example:
public class PropertyExample
{
private int myIntField = 0;
public int MyInt
{
// This is your getter.
// it uses the accessibility of the property (public)
get
{
return myIntField;
}
// this is your setter
// Note: you can specify different accessibility
// for your getter and setter.
protected set
{
// You can put logic into your getters and setters
// since they actually map to functions behind the scenes
if (DoSomeValidation(value))
{
// The input of the setter is always called "value"
// and is of the same type as your property definition
myIntField = value;
}
}
}
}
You would access this property just like a field. For example:
PropertyExample example = new PropertyExample();
example.MyInt = 4; // sets myIntField to 4
Console.WriteLine( example.MyInt ); // prints 4
A few other things to note:
You don't have to specifiy both a getter and a setter, you can omit either one.
Properties are just "syntactic sugar" for your traditional getter and setter. The compiler will actually build get_ and set_ functions behind the scenes (in the compiled IL) and map all references to your property to those functions.
My explanation would be following. (It's not so short, but it's quite simple.)
Imagine a class with a variable:
class Something
{
int weight;
// and other methods, of course, not shown here
}
Well, there is a small problem with this class: no one can see the weight. We could make weight public, but then everyone would be able to change the weight at any moment (which is perhaps not what we want). So, well, we can do a function:
class Something
{
int weight;
public int GetWeight() { return weight; }
// and other methods
}
This is already better, but now everyone instead of plain something.Weight has to type something.GetWeight(), which is, well, ugly.
With properties, we can do the same, but the code stays clean:
class Something
{
public int weight { get; private set; }
// and other methods
}
int w = something.weight // works!
something.weight = x; // doesn't even compile
Nice, so with the properties we have finer control over the variable access.
Another problem: okay, we want the outer code to be able to set weight, but we'd like to control its value, and not allow the weights lower than 100. Moreover, there are is some other inner variable density, which depends on weight, so we'd want to recalculate the density as soon as the weight changes.
This is traditionally achieved in the following way:
class Something
{
int weight;
public int SetWeight(int w)
{
if (w < 100)
throw new ArgumentException("weight too small");
weight = w;
RecalculateDensity();
}
// and other methods
}
something.SetWeight(anotherSomething.GetWeight() + 1);
But again, we don't want expose to our clients that setting the weight is a complicated operation, it's semantically nothing but assigning a new weight. So the code with a setter looks the same way, but nicer:
class Something
{
private int _w;
public int Weight
{
get { return _w; }
set
{
if (value < 100)
throw new ArgumentException("weight too small");
_w = value;
RecalculateDensity();
}
}
// and other methods
}
something.Weight = otherSomething.Weight + 1; // much cleaner, right?
So, no doubt, properties are "just" a syntactic sugar. But it makes the client's code be better. Interestingly, the need for property-like things arises very often, you can check how often you find the functions like GetXXX() and SetXXX() in the other languages.
Most languages do it this way, and you can do it in C# too.
public void setRAM(int RAM)
{
this.RAM = RAM;
}
public int getRAM()
{
return this.RAM;
}
But C# also gives a more elegant solution to this:
public class Computer
{
int ram;
public int RAM
{
get
{
return ram;
}
set
{
ram = value; // value is a reserved word and it is a variable that holds the input that is given to ram ( like in the example below )
}
}
}
And later access it with:
Computer comp = new Computer();
comp.RAM = 1024;
int var = comp.RAM;
For newer versions of C# it's even better:
public class Computer
{
public int RAM { get; set; }
}
and later:
Computer comp = new Computer();
comp.RAM = 1024;
int var = comp.RAM;
C# introduces properties which do most of the heavy lifting for you...
ie
public string Name { get; set; }
is a C# shortcut to writing...
private string _name;
public string getName { return _name; }
public void setName(string value) { _name = value; }
Basically getters and setters are just means of helping encapsulation. When you make a class you have several class variables that perhaps you want to expose to other classes to allow them to get a glimpse of some of the data you store. While just making the variables public to begin with may seem like an acceptable alternative, in the long run you will regret letting other classes manipulate your classes member variables directly. If you force them to do it through a setter, you can add logic to ensure no strange values ever occur, and you can always change that logic in the future without effecting things already manipulating this class.
ie
private string _name;
public string getName { return _name; }
public void setName(string value)
{
//Don't want things setting my Name to null
if (value == null)
{
throw new InvalidInputException();
}
_name = value;
}
well here is common usage of getter setter in actual use case,
public class OrderItem
{
public int Id {get;set;}
public int quantity {get;set;}
public int Price {get;set;}
public int TotalAmount {get {return this.quantity *this.Price;}set;}
}
This would be a get/set in C# using the smallest amount of code possible. You get auto-implemented properties in C# 3.0+.
public class Contact
{
public string Name { get; set; }
}
As far as I understand getters and setters are to improve encapsulation.
There is nothing complex about them in C#.
You define a property of on object like this:
int m_colorValue = 0;
public int Color
{
set { m_colorValue = value; }
get { return m_colorValue; }
}
This is the most simple use. It basically sets an internal variable or retrieves its value.
You use a Property like this:
someObject.Color = 222; // sets a color 222
int color = someObject.Color // gets the color of the object
You could eventually do some processing on the value in the setters or getters like this:
public int Color
{
set { m_colorValue = value + 5; }
get { return m_colorValue - 30; }
}
if you skip set or get, your property will be read or write only. That's how I understand the stuff.
Simple example
public class Simple
{
public int Propery { get; set; }
}
Getters and Setters in C# are something that simplifies the code.
private string name = "spots";
public string Name
{
get { return name; }
set { name = value; }
}
And calling it (assume we have a person obj with a name property):
Console.WriteLine(Person.Name); //prints "spots"
Person.Name = "stops";
Console.Writeline(Person.Name); //prints "stops"
This simplifies your code. Where in Java you might have to have two methods, one to Get() and one to Set() the property, in C# it is all done in one spot. I usually do this at the start of my classes:
public string foobar {get; set;}
This creates a getter and setter for my foobar property. Calling it is the same way as shown before. Somethings to note are that you don't have to include both get and set. If you don't want the property being modified, don't include set!
Internally, getters and setters are just methods. When C# compiles, it generates methods for your getters and setters like this, for example:
public int get_MyProperty() { ... }
public void set_MyProperty(int value) { ... }
C# allows you to declare these methods using a short-hand syntax. The line below will be compiled into the methods above when you build your application.
public int MyProperty { get; set; }
or
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; } // value is an implicit parameter containing the value being assigned to the property.
}
This is a basic example of an object "Article" with getters and setters:
public class Article
{
public String title;
public String link;
public String description;
public string getTitle()
{
return title;
}
public void setTitle(string value)
{
title = value;
}
public string getLink()
{
return link;
}
public void setLink(string value)
{
link = value;
}
public string getDescription()
{
return description;
}
public void setDescription(string value)
{
description = value;
}
}
In case someone is looking for a short version of getter only (I was):
public class Foo
{
private string bar;
public string Bar => bar;
}

how to assign value to readonly static field

I have a field which is static and readonly. The requirement is that the value should be allocated to the field at the login time and after that it should be readonly. How can i achieve this ?
public static class Constant
{
public static readonly string name;
}
Kindly guide.
If you declare a readonly field you can only set it in the constructor of the class. What you could do is implementing a property only having a getter and exposing a change method that is used during your logon sequence to modify the value. Other Parts of your program can use the property effectivly not allowing them to change the value.
public static class Constant
{
public static string Name
{
get
{
return name;
}
set
{
if (name == null)
name = value;
else
throw new Exception("...");
}
}
private static string name;
}
you need a static constructor
public static class Constant
{
public static readonly string name;
static Constant()
{
name = "abc";
}
}
Just assign the value in the declaration (or constructor) like this:
public static class Constant
{
public static readonly string name = "MyName";
}
readonly is sugar for the compiler, telling him, that you don't intend to change the value outside the constructor. If you do so, he will generate an error.
You can also create a static constructor in your static class
static Constant()
{
name = "Name";
}

Public Enumeration with only string values

I'm always confused which kind of enumeration I should use. A hashtable, an enum, a struct a dictionary, an array (how oldschool), static strings...
Instead of using strings in my code I want to use a beautiful enum like so:
public enum MyConfigs
{
Configuration1,
Configuration2
}
Problem is that I don't always want to convert my enum toString() as I'm not interested in the index representation of the enum.
What is the best way to represent a public enumeration of string based values?
In the end I would love to end up with using MyConfigs.Configuration1 where needed in my code.
I prefer defining "grouped" constants as static members of a dummy static class, like so:
public static class FieldNames
{
public const string BRANCH_CODE = "_frsBranchCode";
public const string BATCH_ID = "_frsBatchId";
public const string OFFICE_TYPE = "_frsOfficeType";
}
But of course they are not "enumerable" directly, so you can't foreach over them unless you provide a static array too:
public static string[] AllFieldNames
{
get
{
return new string[]
{
FieldNames.BRANCH_CODE,
FieldNames.BATCH_ID,
FieldNames.OFFICE_TYPE
};
}
}
public static class MyConfigs
{
public const string Configuration1 = "foo",
Configuration2 = "bar"
}
This is then pretty-much identical to how enums are implemented (ignoring the whole "it must be an integer" thing).
Type-safe enum pattern?
public class StringEnum
{
#region Enum Values
public static readonly StringEnum ValueOne = new StringEnum("Value One");
public static readonly StringEnum ValueTwo = new StringEnum("Value Two");
#endregion
#region Enum Functionality
public readonly string Value;
private StringEnum(string value)
{
Value = value;
}
public override string ToString()
{
return value;
}
#endregion
}
You can use this like:
private void Foo(StringEnum enumVal)
{
return "String value: " + enumVal;
}
If you never need to pass these values around in a type-safe manner to methods etc. then it is probably best to just stick with a constants file.

Categories