"Strange" C# Property Syntax

“Strange” C# property syntax

It is an Indexer.

Indexers allow instances of a class or struct to be indexed just like
arrays. Indexers resemble properties except that their accessors take
parameters.
An indexer provides array-like syntax. It allows a type to be accessed
the same way as an array. Properties such as indexers often access a
backing store. We often accept a parameter of int type and access a
backing store of array type.

Read it from http://www.dotnetperls.com/indexer

string s = "hello";
Console.WriteLine (s[0]); // 'h'
Console.WriteLine (s[3]); // 'l'

Implementing an indexer

To write an indexer, define a property called this, specifying the arguments in square
brackets. For instance:

class Sentence
{
string[] words = "The quick brown fox".Split();
public string this [int wordNum] // indexer
{
get { return words [wordNum]; }
set { words [wordNum] = value; }
}
}

Here’s how we could use this indexer:

Sentence s = new Sentence();
Console.WriteLine (s[3]); // fox
s[3] = "kangaroo";
Console.WriteLine (s[3]); // kangaroo

A type may declare multiple indexers, each with parameters of different types. An
indexer can also take more than one parameter:

public string this [int arg1, string arg2]
{
get { ... } set { ... }
}

Indexers internally compile to methods called get_Item and set_Item, as follows:

public string get_Item (int wordNum) {...}
public void set_Item (int wordNum, string value) {...}

The compiler chooses the name Item by default—you can actually change this by
decorating your indexer with the following attribute:

[System.Runtime.CompilerServices.IndexerName ("Blah")]

What's this strange C# syntax and how do I build it?

=> is a new operator in C# 6 and indicates an Expression Bodied Function to use for that getter.

Your two examples are synonymous as far as the compiler is concerned and merely return the value assigned. The => is syntactic sugar to make development a bit easier and require fewer lines of code to achieve the same outcome.

However, you won't be able to compile unless you update to VS2015 with the latest compiler version.

Edit:

As said by Philip Kendall and Carl Leth in the comments, the first lines in each are not exactly synonymous as public const int CurrentHp = 10; is a field and public int CurrentHp { get; } = 10; is a property. Although at a high level the outcome is the same (assigning a value of 10 to CurrentHp with the property only being settable in the class constructor), they differ in that:

With const int CurrentHp = 10, CurrentHp will always be 10, take up 4 total bytes, and can be accessed statically. int CurrentHp { get; } = 10defaults to 10, but can be changed in the constructor of F and thereby can be different per instance and cannot be accessed statically.

Weird C# syntax

That statement doesn't just economize 3 lines, it more readable and also spares a code block, which is important to allow more complex LINQ queries.

What do you think of these two?

var x = collection.Select(x => new SomeClass(x?.Property ?? "default"));

Opposed to:

var x = collection.Select(x => 
{
string value = null;
if (x != null)
{
value = x.Property;
}

if (value == null)
{
value = "default";
}

return new SomeClass(value);
}
);

The first is much more expressive and powerful. And what if you have more than one property?

Just started learning C# & ASP.NET - strange syntax (to me) and I don't know what it is

In c#, you define arrays like this:

string[] companies = new string[3] {"Google", "Microsoft", "Facebook"}; //3 is the size and it's necessary when defining array without items. (It isn't necessary now)

So unlike python or javascript, array items are not located inside square brackets.

But there is another thing called an attribute.

Attributes are special classes that inherit from the Attribute class and you use the constructor of that class in square brackets before the property or method or variable that you want the attribute to apply to it.
In this example, You apply the JsonPropertyName attribute to the Image as the following:

[JsonPropertyName("img")]
public string Image { get; set; }

The JsonSerializer.Serialize<Product>(this) will check each property's attribute (if it has one) and applies that attribute while serializing. When you Serialize an instance of this class using the overridden ToString() method, this attribute forces the serializer to use img for JSON property name instead of Image so you will get img instead of Image in JSON.

Example without using attribute:

{
"Id": <Id>,
"Maker": <Maker>,
"Image": <Image>, //Image
"Url": <Url>,
"Title": <Title>,
"Description": <Description>,
"Ratings": [<Ratings>]
}

But when you use [JsonPropertyName("img")] attribute, it will look like this:

{
"Id": <Id>,
"Maker": <Maker>,
"img": <Image>, //img
"Url": <Url>,
"Title": <Title>,
"Description": <Description>,
"Ratings": [<Ratings>]
}

For more information about this attribute you can refer to following links:

usage and
structure

And for more information about attributes, visit this.

What does the = operator mean in a property or method?

What you're looking at is an expression-bodied member not a lambda expression.

When the compiler encounters an expression-bodied property member, it essentially converts it to a getter like this:

public int MaxHealth
{
get
{
return Memory[Address].IsValid ? Memory[Address].Read<int>(Offs.Life.MaxHp) : 0;
}
}

(You can verify this for yourself by pumping the code into a tool called TryRoslyn.)

Expression-bodied members - like most C# 6 features - are just syntactic sugar. This means that they don’t provide functionality that couldn't otherwise be achieved through existing features. Instead, these new features allow a more expressive and succinct syntax to be used

As you can see, expression-bodied members have a handful of shortcuts that make property members more compact:

  • There is no need to use a return statement because the compiler can infer that you want to return the result of the expression
  • There is no need to create a statement block because the body is only one expression
  • There is no need to use the get keyword because it is implied by the use of the expression-bodied member syntax.

I have made the final point bold because it is relevant to your actual question, which I will answer now.

The difference between...

// expression-bodied member property
public int MaxHealth => x ? y:z;

And...

// field with field initializer
public int MaxHealth = x ? y:z;

Is the same as the difference between...

public int MaxHealth
{
get
{
return x ? y:z;
}
}

And...

public int MaxHealth = x ? y:z;

Which - if you understand properties - should be obvious.

Just to be clear, though: the first listing is a property with a getter under the hood that will be called each time you access it. The second listing is is a field with a field initializer, whose expression is only evaluated once, when the type is instantiated.

This difference in syntax is actually quite subtle and can lead to a "gotcha" which is described by Bill Wagner in a post entitled "A C# 6 gotcha: Initialization vs. Expression Bodied Members".

While expression-bodied members are lambda expression-like, they are not lambda expressions. The fundamental difference is that a lambda expression results in either a delegate instance or an expression tree. Expression-bodied members are just a directive to the compiler to generate a property behind the scenes. The similarity (more or less) starts and end with the arrow (=>).

I'll also add that expression-bodied members are not limited to property members. They work on all these members:

  • Properties
  • Indexers
  • Methods
  • Operators

Added in C# 7.0

  • Constructors
  • Finalizers

However, they do not work on these members:

  • Nested Types
  • Events
  • Fields

Head First C#: strange way to create a read-only property

The primary difference between the two samples is, as you have noticed, that one has a backing field (which is what putting decimal cost outside the property definition does) and the other doesn't.

The totalCost variable in the second sample isn't a field at all (private or otherwise), it is simply a variable local to the get method.

Both are fine, though if you aren't using the backing field for anything, its not really necessary to have. As to your second question, I have no idea why they specifically did it that way, other than to make the variable declaration simpler.

As an aside, both samples are a bit off from standard C# practice, as thats an awful lot of logic for a property getter.

What is the this[parameter] syntax for?

It is an indexer:

Indexers allow instances of a class or struct to be indexed just like arrays. Indexers resemble properties except that their accessors take parameters.

These are normally used in collection types - dictionaries, lists and arrays for example.

In the specific example you have given, a method appears to be more appropriate.

Strange C# syntax

If you add parens it's easier to read (and understand). The logical comparison operator != precedes the assignment operator =:

base.DialogResult = (this.Result != null);

The same statement, even more verbose:

if (this.Result != null)
base.DialogResult = true;
else
base.DialogResult = false;


Related Topics



Leave a reply



Submit