Question

is there any effective difference between Foo.Something and Bar.Something in this example?

class Foo
{
    public string Something;
}

class Bar
{
    public string Something{get; set;}
}

class Program
{
    static void Main(string[] args)
    {
        var MyFoo = new Foo();
        MyFoo.Something = "Hello: foo";
        System.Console.WriteLine(MyFoo.Something);

        var MyBar = new Bar();
        MyBar.Something = "Hello: bar";
        System.Console.WriteLine(MyBar.Something);
        System.Console.ReadLine();
    }
}

AFAIK they behave exactly the same. If they do why not to use plain Fields like in Foo? In java we use setters to be able enforce new invariants without breaking code and getters to return safe data but in c# you can always rewrite Foo into this:

class Foo
{
    private string _Something;
    public string Something
    {
        get { 
            //logic
            return _Something; 
            }
        set { 
            //check new invariant
            _Something = value; 
            }
    }
}

And old code will not be broken.

Was it helpful?

Solution

AFAIK they behave exactly the same.

No they don't.

  • Fields can't be used in data binding (at least in some binding implementations)
  • You can add more logic later for properties without breaking source or binary compatibility
  • Properties can't be passed by reference
  • You can't add an initializer to an automatically implemented property
  • They'll clearly be different in terms of reflection
  • Philosophically, properties are logically part of the API whereas fields are an implementation detail

in c# you can always rewrite Foo into this: [...]

Well you can if you don't care about binary or source compatibility, yes. In some cases that's really not an issue - in other cases it's very, very much an issue. Why not make the choice to expose your API rather than your implementation details from the start? It's not like adding { get; set; } in your code is adding much clutter...

For more ranting, see my article on this.

OTHER TIPS

Foo.Something is a field, Bar.Something is an automatically implemented property. That's a huge difference.

You can just access properties the same way as fields, but internally a set/get method is called when you access a property.

So when you say myBar.Something = "asdf", the C# compiler translates this to a call to a setter method: myBar.set_Something("asdf"). The setter and getter methods are generated automatically for you, as well as a backing field for the actual value.

By changing Foo.Something to a property with get and set methods, you are breaking binary compatibility, that means you'll have to recompile all assemblies that used Foo.Something when it still was a field.

The getters and setters of a property (including automatic ones) have a method call cost. Public fields should be avoided in order to keep things clean with access.

public string Something{get; set;} is just syntactic sugar; the compiler actually expands this to methods. So there is little point in having all get; set; fields all over the place, just for the sake of it.

1) You can add private accessor to get or set and control access to property.

public object MyProp {get; private set;}

You can read prop everywhere, but write only inside class

2) You can connect some logic to read/write property. In case of field you can not do anything additional

3) You can not serialize fields

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top