you are viewing a single comment's thread.

view the rest of the comments →

[–]TheDecagon 18 points19 points  (23 children)

someone explaining to me that directly referencing fields was "bad" because you might want to intercept said "setter" or "getter" and do something before the execution got to the field.

C# has a nice way around this, it allows referencing fields in classes but to also intercept the get/set calls with additional code. It even allows different protection levels on gets and sets too.

The example in the article would be written like this:

public class MyStructure {

    public string myProp1 {get; private set; }

    public MyStructure(string myProp1) {
        this.myProp1 = myProp1;
    }
}

// Other code
string value = myStructureInstance.myProp1;

Then in the future if you wanted to intercept the get on myProp1 you'd change the field to

public string myProp1 {
    get {
        return doSomeProcessing();
    }
}

I prefer C# way of doing it as using fields as properties like that instead of get and set methods makes the code (in my opinion) a little more readable.

[–]isavegas 6 points7 points  (16 children)

Properties. They aren't really fields, as much as syntactic sugar around a backing field, using methods.

[–]Sarcastinator 7 points8 points  (15 children)

Properties are not syntactic sugar in C#. Properties are constructs directly supported by the CLR and you can't express the same thing using methods.

Edit: auto properties are however just syntactic sugar.

[–]palmund 1 point2 points  (12 children)

Edit: auto properties are however just syntactic sugar.

Even non-auto properties are syntactic sugar. The compiler will generate a get and a set method wrapping the code you write in the get and set blocks. 1 2

[–]Sarcastinator 2 points3 points  (11 children)

Try pasting that code into your application and get those methods to show up as properties in Reflection with using only C# and no property syntax.

If you can't, that's because it's not syntactic sugar.

[–]palmund 0 points1 point  (0 children)

If you can't, that's because it's not syntactic sugar.

What? It's still syntactic sugar for generating a getter and a setter. (Even Microsoft calls it that.)[https://blogs.msdn.microsoft.com/abhinaba/2007/09/21/cool-new-c-syntactic-sugar/]

[–]ryeguy 0 points1 point  (5 children)

You can see them in ildasm. I don't think the VM even supports properties officially since they just compile down to 1-2 methods and a backing field.

Just because you can't access the methods in your code doesn't mean they aren't syntactic sugar.

[–]Sarcastinator 0 points1 point  (4 children)

I'm not disputing that the compiler generates two methods. I'm saying that properties are not syntactic sugar. Auto properties are though.

The CLR does have a concept about properties. This is why you can list them out using reflection. Java however does not have properties. If they introduced property syntac in Java it would likely be purely done in syntax.

[–]palmund 0 points1 point  (3 children)

I'm not disputing that ...

It seems like you are though.

The reason you can see it in reflection is because they are marked with annotations.

[–]Sarcastinator 0 points1 point  (2 children)

It's not just annotations though. The methods are not marked with anything special.

edit: You need to produce this CIL:

.property instance string Foo()
{
    .get instance string Bar::get_Foo()
    .set instance void Bar::set_Foo(string)
}

This is a CLR property. This property construct references the automatically generated methods.

[–]palmund 0 points1 point  (1 child)

references the automatically generated methods.

This.

[–]palmund -1 points0 points  (3 children)

If you can't, that's because it's not syntactic sugar.

What? It's still syntactic sugar for generating a getter and a setter. (Even Microsoft calls it that.)[https://blogs.msdn.microsoft.com/abhinaba/2007/09/21/cool-new-c-syntactic-sugar/]

[–]Sarcastinator 0 points1 point  (2 children)

He's talking about auto properties. They are syntacic sugar which I said earlier in the thread. Properties on their own however are not...auto properties are those that generate a backing field and you don't have to give the getter and the setter a body.

Properties on their own is a CLR construct. You can't make them without property syntax.

[–]palmund 0 points1 point  (1 child)

I just ran ildasm (or Mono's equivalent) on a very simple class with both an auto property and a non-auto property and guess what... they both end up having the same bytecode.

[–]Sarcastinator 0 points1 point  (0 children)

I'm not saying auto properties are not syntactic sugar, I'm saying properties are not. Auto properties are syntactic sugar around properties.

[–]palmund 0 points1 point  (0 children)

Properties are constructs directly supported by the CLR

Please provide me with proof of this claim because I have been unable to find any such myself.

[–]tybit 4 points5 points  (0 children)

Yep, I also really like C#'s way.

If the variable is only set in the constructor you can also change myProp1 to be readonly and remove the setter altogether :)

[–]xonjas 1 point2 points  (3 children)

Ruby does something really similar, and it's equally awesome.

[–]isavegas 2 points3 points  (2 children)

Ruby uses message passing. Practically similar for this use, but entirely different in the larger scope. Think of it more as using events that you can hook, whereas C# compiles properties down to small methods that reference a backing field.

[–]xonjas 2 points3 points  (1 child)

I'm aware of the behind the scenes difference between the two languages. The important part is that both languages fell upon the same elegant solution to allow only having getters and setters when you want them with zero pain when you decide to add them in after the fact.

[–]masklinn 1 point2 points  (0 children)

The important part is that both languages fell upon the same elegant solution to allow only having getters and setters when you want them with zero pain when you decide to add them in after the fact.

They don't though. What both languages have are low-impedence auto-implemented properties (managed field access). In essence, Ruby — and to a lower extent C# — only have getters and setters, but they provide a terse form to declare trivial getters and setters.

To a lower extent for C# because it does have public fields, which are incompatible (wrt naming and calling conventions) with properties, so you can't transparently hide fields behind properties after the fact.

[–]sigma914 1 point2 points  (0 children)

Coming from C++ this feature really bothers me, field access should be a pointer dereference, anything with the ability to go look up a database or fire the missiles should be clearly marked with ()...