I know the purpose that C# properties were originally designed for, which is certainly useful. However instead in this question I'm comparing them more abstractly to functions and other programic elements.

Firstly, I wondered, if it were possible, and if so why not, to have a function like C# property.

The above example defines "test" along with reasonably fine detail involving different implementations for using test in various different ways.

More examples:

Read only:

byte test
{
get
{
}
}

Function like:

test
{
func
{
}
}

Function like with parameter polymorphism, returns a byte:

byte test
{
func(bool)
{
}
func(myType, Int16)
{
}
}

Behaves differntly depending on the type assigned to it:

test
{
set bool
{
}
set myType
{
}
}

Function like and could return a value or not, depending on the context it is used:

test
{
byte get
{
}
func(bool)
{
}
func(byte, byte, myType)
{
}
}

The additional possibility for expression and code tidiness should be apparent. However I have been challenged to find specific uses.

One example of how this could be used is equality. Where a bool is expected, for example in an 'if' statement, the behaviour could be defined as being '==', however where there was either nothing to return to, or the return to was other than bool, the behaviour would instead be '='.

You need to show an example of this making real code more expressive then the alternative. If you can't show a single concrete example, why do you think it is worth the cost of adding?
–
Chris PitmanApr 7 '12 at 23:20

I'm not sure if you're saying you want to have functions with the return type of byte to implicitly convert to a byte property or if your saying you want properties where you can assign functions but not call until you write (). Also check out C#'s Func<T, TRet> and Action<T>
–
acidzombie24Apr 21 '12 at 4:12

Properties represent a well-defined concept: they represent some value that can be read and (optionally) written. I think it doesn't make much sense to expand it the way you're proposing, it just doesn't make sense conceptually to me.

I think that func “accessor” just doesn't belong there, it should be separate from the get and set accessors. And the code that uses it is confusing: just value as a statement shouldn't do anything, I certainly wouldn't expect it to do n++.

Also, what should be the meaning of your func accessor in general? “Any additional code related to the property”? I think that would be a really bad idea, you should be able to look at code and understand what it does, without inspecting the code of every method called.

All in all, I think creating a separate method with a name that clearly explains what it does is much better than your proposal.

As a side note, you actually can do this in IL. A property is just a grouping of several methods. And those methods are marked as Getter, Setter or Other. You could use those Other methods to do whatever you wanted, but you would need to write your own compiler for it (or modify existing one).

This example is arbitrary with the 'n++' as it's just an example. Just as 'get' and 'set' are optional, so would 'func' be, and mostly in accessor type situations one can easily imagine where it wouldn't be used just as there are situations where only get is implemented. It could however be used for a computationally simpler version of a function that can return a value but dosn't in some context. Also in the case of functions that return no values I think "func()" is less neat than "func".
–
alan2hereApr 7 '12 at 22:15

But that's part of of my point: it's not clear what should func do. If I call it, what should I expect to happen? I shouldn't look at documentation or implementation to figure out what some piece of code does. But your func does exactly that. And I have no idea what you mean by “computationally simpler version of a function that can return a value but dosn't in some context”.
–
svickApr 7 '12 at 22:28

I mean that a function that performs a calculation then returns a value requiring another calculation could be broken into two functions with the same name, that take the same (or no) parameters, there would then be polymorphism between whether the function was called on it's own, or on the right hand side of an equals. The stand alone version would be computationally simpler, for example not requiring processing of the returned value.
–
alan2hereApr 7 '12 at 22:38

So you're saying this would be useful if you have a getter that has observable side-effects? But that's not a good practice, getters should not have observable side effects. Right now, it seems to me you want this feature to simplify writing bad code.
–
svickApr 7 '12 at 22:42

It's not a "getter" in the "get_xyz" or "set_xyz" member function sence. It's just a function. It's only a getter if used in that context. Unfortunatly the name and it's historical context sugest that it only has one use.
–
alan2hereApr 7 '12 at 23:21

First, it isn't clear what your func is supposed to do. A property has a getter and a setter because it gets or sets the value of a clearly (if you are sensible) named property.

If your func, in this example returns current value + 1, how am I supposed to know what it does without calling it? I'd rather see a method called GetNextN()

Properties generally shouldn't mess about with the state of a property too much. That's why they are properties. If you want to mutate stuff, use a method with a clear name explaining the mutating behaviour.

What would you expect if I called any of the following:

func++;
byte v = func++;

?

So I think the reason we wouldn't see this added to the language is that it doesn't offer anything we can't already do in a much clearer fashion.

It's of course situational, as 'get' and 'set' are, there not always both supplied, and ofc 'n++' is just an example, it's not a particually sensible one, just a simple one to express in this example that I perhaps should have made more apparent. Also properties can be used just like functions. I'm not sure where the idea that they shouldn't contain too much computation comes from, I've heard it repeated a lot though, probably from there original intention as merely automating a common process.
–
alan2hereApr 7 '12 at 22:40

func++ wouldn't work on my class unless I implemented ++, and 'byte v = func = 4;' for example has the same getting and setting ambiguity that current properties must have, presumably where both and defined both the get and set occur.
–
alan2hereApr 8 '12 at 0:20

Why? Aren't you happy with the existent C# syntax? In order to change the syntax of a language, there must be serious reasons to do it.

Getters and setters make it easier to write code, and were a positive change through the evolution of C#. Yours, on the other hand, doesn't bring anything particularly useful. Not counting that it's hard to understand what does the piece of code in your example.

Now think about the consequences. For example, what about static analysis (and all the tools which rely on the existent syntax)?

Lots of changes occured in recent versions of C# such as in 3 and 4, including some major stuff like the dynamic keyword. Although I don't know what could be classed as a syntactic change. There is only a very small amount of my example that are different from whats possible with standard properties, I don't see how it could be called confusing beyond the arbitrariness of my trvial example program. If there has to be a big reason for making a change then they may as well give up now, the world turns and things are improved every day. I love C# over, for example C++, but it's far from optimal.
–
alan2hereApr 7 '12 at 21:55

Furthermore I like ability to specify and express a varying degree of detail in the function and it's interface so that others can use the function smoothly. This seems like the next step. I don't see how "func();" for a no argument function is better than "func;", to me it seems worse. I'm always carefull when thinking about a change, it's easy to see the change as being worse because it's different, things are however generally improved into the future not the past.
–
alan2hereApr 7 '12 at 21:59

2

@alan2here, for one, the distinction is there to disambiguate between taking a delegate to a method and calling that method. Both SomeType x = func; and AnotherType y = func(); can compile and they do completely different things.
–
svickApr 7 '12 at 22:10

Presumably a function expressed using a property and 'get' has this ambiguity at the moment. This does however make changing it more troublesome and less likely seeming.
–
alan2hereApr 7 '12 at 22:20

@svick I think you should edit your answer above to include the comment here.
–
Joshua DrakeApr 10 '12 at 15:54

You may have a point if you want to make the proposed function specific to a given property only and can't be called by other parts of code within even the same class.

Say you want to return the value of pi via a calculation and that calculation is so complex that you can't simply perform it in a set statement. The current approach is to call one or methods of the class before you could return the result. However, those methods would be exposed to the rest of the class unnecessarily and they may be called by mistake by say, a partial class developer that do not know what they are doing.

In the above scenario, introducing your concept of a function can be helpful because the function will not be called by code outside the property, hence protecting from a possible mistake. However, in no way properties should go away :)