Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've been thinking about how C# properties work and could work.

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.

For example:

byte n = 4;

byte test // property
{
    get
    {
        return n;
    }
    set
    {
        n = value;
    }
    func
    {
        n++;
    }
}

To use as follows:

// n is 4
byte n2 = test; // get
test = 2; // set
// n is now 2
test; // function
// n is now 3

The 'n++' in this example being used only as a simple demonstration.

I also noticed that there is room for more polymorphism than just in function parameter types. For example having overload resolution by return type, get/set and private/public as well.

public test
{
    get
    {
    }
    get byte
    {
    }
    private get byte
    {
    }
    get bool
    {
    }
    get myType
    {
    }
    set byte
    {
    }
    set myType
    {
    }
    func
    {
    }
    func(bool)
    {
    }
    func(byte, myType)
    {
    }
    // etc...
}

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 '='.

if (n.equals(4)) // if n == 4
    n.equals(2); // n = 2

Another example is as follows:

class my_list<T>
{
    List<T> store;
    public count
    {
        get
        {
            // unless otherwise apparent,
            // use the Int32 version.
            return (Int32)count;
        }

        get byte
        {
            byte n = 0;
            ForEach(var e in store)
                n++;
            return n;
        }

        get Int32
        {
            Int32 n = 0;
            ForEach(var e in store)
                n++;
            return n;
        }

        private get
        {
            // An implmentation of "count get" that only
            // occurs when count is used from inside the
            // my_list class.
        }

        func
        {
            print store.Count();
        }

        set int
        {
            if (value == 0)
                list.Clear();
        }
    }
}
share|improve this question
    
Does the above code compile? –  Emmad Kareem Apr 7 '12 at 21:33
    
No, the "func {n++;}" bit is hypothetical for now. –  alan2here Apr 7 '12 at 21:44
5  
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 Pitman Apr 7 '12 at 23:20
    
Your question is way to long. Why don't you simply say what you like to do(assign functions to properties) and an example of where you would use it. If you want check out any question i write. stackoverflow.com/users/34537/acidzombie24?tab=questions –  acidzombie24 Apr 21 '12 at 4:09
    
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> –  acidzombie24 Apr 21 '12 at 4:12

6 Answers 6

I've tried to model what you are looking for using what's already available in the language. It kind of looks the same as your example:

public class Test
{
    private class SuperByteProperty : SuperProperty<byte>
    {
        public SuperByteProperty(byte v)
        {
            Get = () =>
            {
                return v;
            };
            Set = newValue =>
            {
                v = newValue;
            };
            Func = () =>
            {
                v++;
            };
        }
    }

    public void Run()
    {
        var n = new SuperByteProperty(4);
        Console.WriteLine(n.Get()); // outputs 4
        n.Set(2);
        Console.WriteLine(n.Get()); // outputs 2
        n.Func();
        Console.WriteLine(n.Get()); // outputs 3
    }
}

I'm basically creating a class holding three closures (closing over the free variable v). Here's the implementation of the SuperProperty:

public class SuperProperty<T>
{
    public Func<T> Get { get; protected set; }
    public Action<T> Set { get; protected set; }
    public Action Func { get; protected set; }
}

This is heavily inspired by Nancy btw.

share|improve this answer
    
lol, close :¬P and thanks :¬) However 'n.Set(2);' is just a function call, as is 'n.Func()'. 'run() {...}' should look more like this "var n = new SuperByteProperty(4); Console.WriteLine(n); n = 2; Console.WriteLine(n); n; Console.WriteLine(n);" –  alan2here Apr 8 '12 at 0:10
    
Why the closures instead of methods? –  user281377 Apr 20 '12 at 17:55
    
I was just trying to match the syntax requested.. –  Torbjørn Apr 21 '12 at 10:45

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).

share|improve this answer
    
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". –  alan2here Apr 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”. –  svick Apr 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. –  alan2here Apr 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. –  svick Apr 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. –  alan2here Apr 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.

share|improve this answer
    
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. –  alan2here Apr 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. –  alan2here Apr 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)?

share|improve this answer
    
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. –  alan2here Apr 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. –  alan2here Apr 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. –  svick Apr 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. –  alan2here Apr 7 '12 at 22:20
    
@svick I think you should edit your answer above to include the comment here. –  Joshua Drake Apr 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 :)

share|improve this answer

You can try something like this. It uses a property as a function, and, although it's not in the format you specified, it's the closest thing I can think of:

using System;
using System.Collections;

namespace Properties_As_Functions
{
public class Functions
{
    public ArrayList Function
    {
        set
        {
            ArrayList returnValue = new ArrayList();

            foreach (object param in value)
            {
                if (param is string)
                {
                    if ((param as string) == "Hi!")
                        returnValue.Add("Hello!");
                    else
                        returnValue.Add("No!");
                }
            }

            FunctionReturnValue = returnValue;
        }
    }

    public ArrayList FunctionReturnValue = new ArrayList();
}

public class Program
{
    public static void Main()
    {
        Functions functions = new Functions();

        ArrayList parameters = new ArrayList();
        ArrayList returnValue = new ArrayList();

        parameters.Add("Hi!");
        parameters.Add("Nope!");

        functions.Function = parameters;

        returnValue = functions.FunctionReturnValue;

        foreach (object param in returnValue)
        {
            if (param is string)
                Console.WriteLine(param as string);
        }
    }
}
}
share|improve this answer
    
how does this answer the question asked? –  gnat Aug 20 '13 at 21:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.