142

I realize that it seems to be a duplicate of What is the difference between a Field and a Property in C#? but my question has a slight difference (from my point of view):

Once I know that

  • I will not use my class with "techniques that only works on properties" and
  • I will not use validation code in the getter/setter.

Is there any difference (except the style/future development ones), like some type of control in setting the property?

Is there any additional difference between:

public string MyString { get; set; }

and

public string myString;

(I am aware that, that the first version requires C# 3.0 or above and that the compiler does create the private fields.)

Community
  • 1
  • 1
p4bl0
  • 4,825
  • 5
  • 22
  • 25
  • possible duplicate of [Auto-implemented getters and setters vs. public fields](http://stackoverflow.com/questions/111461/auto-implemented-getters-and-setters-vs-public-fields) – nawfal Jun 03 '13 at 18:39

10 Answers10

165

Fields and properties look the same, but they are not. Properties are methods and as such there are certain things that are not supported for properties, and some things that may happen with properties but never in the case of fields.

Here's a list of differences:

  • Fields can be used as input to out/ref arguments. Properties can not.
  • A field will always yield the same result when called multiple times (if we leave out issues with multiple threads). A property such as DateTime.Now is not always equal to itself.
  • Properties may throw exceptions - fields will never do that.
  • Properties may have side effects or take a really long time to execute. Fields have no side effects and will always be as fast as can be expected for the given type.
  • Properties support different accessibility for getters/setters - fields do not (but fields can be made readonly)
  • When using reflection the properties and fields are treated as different MemberTypes so they are located differently (GetFields vs GetProperties for example)
  • The JIT Compiler may treat property access very differently compared to field access. It may however compile down to identical native code but the scope for difference is there.
Brian Rasmussen
  • 109,816
  • 33
  • 208
  • 305
  • 11
    Note however that several of these points should *not* be differences if good practices are employed. That is, properties really should never have side effects, nor should they take a long time to execute. – Noldorin Jan 07 '12 at 21:20
  • 15
    @Noldorin: I agree, but unfortunately *should* is the keyword here. With fields that behavior is guaranteed. I'm not saying you should use fields, but it is important to be aware of the semantic differences. – Brian Rasmussen Mar 05 '12 at 17:00
  • 4
    Yeah, fair enough. Beginner programmers don't have a clue about these things oftentimes, unfortunately... – Noldorin Mar 06 '12 at 00:59
  • 2
    Also, fields may have a field initializer while properties have to be initialized in a constructor. – Dio F Apr 30 '13 at 08:57
  • 3
    I feel this answer is magnitudes better than the accepted answer. I'm starting to think that the "acceptable" way of always preferring properties over fields is bad thinking. If you only need to deal with data, use a field. If you need to apply functionality to data, use a method. Since properties may have side-effects you are not aware (especially if you didn't design the library and have little documentation), they seem counter intuitive to me in most cases. – David Peterson Jan 06 '14 at 16:07
  • +1 David to: "I'm starting to think that the 'acceptable' way of always preferring properties over fields is bad thinking.", not because I fully agree, but because I can't stand it when everyone bah's like a bunch of sheep and do something one way because that's what they are "supposed" to do. I've wondered if things have gone a little to far on this issue. As an aside: I would be interested though if the compiler team can speed up property access calls for simple property get/set types (when no other processing exists). – Nicholas Petersen Aug 12 '14 at 21:59
  • @DavidPeterson Then you'd probably be happier using C and its structs to pass data to functions. – Andy Sep 30 '15 at 23:43
119

Encapsulation.

In the second instance you've just defined a variable, in the first, there is a getter / setter around the variable. So if you decide you want to validate the variable at a later date - it will be a lot easier.

Plus they show up differently in Intellisense :)

Edit: Update for OPs updated question - if you want to ignore the other suggestions here, the other reason is that it's simply not good OO design. And if you don't have a very good reason for doing it, always choose a property over a public variable / field.

Mark Ingram
  • 65,792
  • 48
  • 164
  • 225
  • 12
    Why will it be easier? What prevents me from turning a field into a property and add an private backing field? How does this affect calling code? – Serge Wautier Mar 17 '09 at 09:45
  • 31
    @Serge - It affects already compiled code. For example, if you are developing a library that is used by several applications, changing a field to a property in that library would require a recompile of each application. If it were a property, you could update the property without worry. – Dustin Campbell Mar 17 '09 at 09:50
  • I totally agree with you, I use always properties. I was just curious about a possible difference – p4bl0 Mar 17 '09 at 13:23
  • 25
    If consuming code is always recompiled at the same time as the affected class (so anything private or internal without internals visible to is 100% safe) then making it a field is perfectly OK – ShuggyCoUk Mar 17 '09 at 15:13
  • 1
    wow Shuggy your comment is exactly the answer i was looking for! – p4bl0 Mar 17 '09 at 19:13
  • ah well should have made it an answer ;) – ShuggyCoUk Mar 17 '09 at 21:48
  • :) I thought of this when I saw that – ShuggyCoUk Mar 19 '09 at 15:03
  • @ShuggyCoUk This is the answer I was looking for. – styfle Jul 16 '13 at 01:57
  • I'd argue that there *isn't* an encapsulation difference between `public string MyString { get; set; }` and `public string myString;` – Caleth Jul 17 '19 at 15:47
43

A couple quick, obvious differences

  1. A property can have accessor keywords.

    public string MyString { get; private set; }
    
  2. A property can be overridden in descendents.

    public virtual string MyString { get; protected set; }
    
bluish
  • 23,093
  • 23
  • 110
  • 171
Dustin Campbell
  • 9,459
  • 1
  • 29
  • 32
14

The fundamental difference is that a field is a position in memory where data of the specified type is stored. A property represents one or two units of code that are executed to retrieve or set a value of the specified type. The use of these accessor methods is syntactically hidden by using a member that appears to behave like a field (in that it can appear on either side of an assignment operation).

Joshua Stafford
  • 472
  • 2
  • 5
  • 16
AnthonyWJones
  • 178,910
  • 32
  • 227
  • 302
11

Accessors are more than fields. Others have already pointed out several important differences, and I'm going to add one more.

Properties take part in interface classes. For example:

interface IPerson
{
    string FirstName { get; set; }
    string LastName { get; set; }
}

This interface can be satisfied in several ways. For example:

class Person: IPerson
{
    private string _name;
    public string FirstName
    {
        get
        {
            return _name ?? string.Empty;
        }
        set
        {
            if (value == null)
                throw new System.ArgumentNullException("value");
            _name = value;
        }
    }
    ...
}

In this implementation we are protecting both the Person class from getting into an invalid state, as well as the caller from getting null out from the unassigned property.

But we could push the design even further. For example, interface might not deal with the setter. It is quite legitimate to say that consumers of IPerson interface are only interested in getting the property, not in setting it:

interface IPerson
{
    string FirstName { get; }
    string LastName { get; }
}

Previous implementation of the Person class satisfies this interface. The fact that it lets the caller also set the properties is meaningless from the point of view of consumers (who consume IPerson). Additional functionality of the concrete implementation is taken into consideration by, for example, builder:

class PersonBuilder: IPersonBuilder
{
    IPerson BuildPerson(IContext context)
    {

        Person person = new Person();

        person.FirstName = context.GetFirstName();
        person.LastName = context.GetLastName();

        return person;

    }
}

...

void Consumer(IPersonBuilder builder, IContext context)
{
    IPerson person = builder.BuildPerson(context);
    Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}

In this code, consumer doesn't know about property setters - it is not his business to know about it. Consumer only needs getters, and he gets getters from the interface, i.e. from the contract.

Another completely valid implementation of IPerson would be an immutable person class and a corresponding person factory:

class Person: IPerson
{
    public Person(string firstName, string lastName)
    {

        if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName))
            throw new System.ArgumentException();

        this.FirstName = firstName;
        this.LastName = lastName;

    }

    public string FirstName { get; private set; }

    public string LastName { get; private set; }

}

...

class PersonFactory: IPersonFactory
{
    public IPerson CreatePerson(string firstName, string lastName)
    {
        return new Person(firstName, lastName);
    }
}
...
void Consumer(IPersonFactory factory)
{
    IPerson person = factory.CreatePerson("John", "Doe");
    Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}

In this code sample consumer once again has no knowledge of filling the properties. Consumer only deals with getters and concrete implementation (and business logic behind it, like testing if name is empty) is left to the specialized classes - builders and factories. All these operations are utterly impossible with fields.

Zoran Horvat
  • 9,447
  • 3
  • 26
  • 39
8

The first one:

public string MyString {get; set; }

is a property; the second one ( public string MyString ) denotes a field.

The difference is, that certain techniques (ASP.NET databinding for instances), only works on properties, and not on fields. The same is true for XML Serialization: only properties are serialized, fields are not serialized.

Frederik Gheysels
  • 53,692
  • 9
  • 95
  • 146
  • 8
    Wrong. XML Serialization DOES serialize public fields. – Serge Wautier Mar 17 '09 at 09:44
  • 2
    Maybe. But when you create an Object Data Source from a class, you only get to use the properties, not the fields. (Unless I have done something wrong :P) – Svish Mar 17 '09 at 10:00
  • Good is to DRY ;) but i write once again, I like strong role of property in C# language . Is much better implemented than in Java (consequently from the beginning) Many, maybe all .net solutions work on properties only. WPF, ASPX and more. – Jacek Cz Sep 10 '15 at 16:22
2

Properties and Fields may, in many cases, seem similar, but they are not. There are limitations to properties that do not exist for fields, and vice versa.

As others have mentioned. You can make a property read-only or write-only by making it's accessor private. You can't do that with a field. Properties can also be virtual, while fields cannot.

Think of properties as syntactic sugar for getXXX()/setXXX() functions. This is how they are implemented behind the scenes.

Erik Funkenbusch
  • 90,480
  • 27
  • 178
  • 274
1

There is one other important difference between fields and properties.

When using WPF, you can only bind to public properties. Binding to a public field will not work. This is true even when not implementing INotifyPropertyChanged (even though you always should).

BradleyDotNET
  • 57,599
  • 10
  • 90
  • 109
  • Good is to DRY ;) but i write once again, I like strong role of property in C# language . Is much better implemented than in Java (consequently from the beginning) Many, maybe all .net solutions work on properties only. WPF, ASPX and more. – Jacek Cz Sep 10 '15 at 16:21
1

Among other answers and examples, I think this example is useful in some situations.

For example let say you have a OnChange property like following:

public Action OnChange { get; set; }

If you want to use delegates than you need to change it OnChange to field like this:

public event Action OnChange = delegate {};

In such situation we protect our field from unwanted access or modification.

maytham-ɯɐɥʇʎɐɯ
  • 21,551
  • 10
  • 85
  • 103
0

You should always use properties instead of fields for any public fields.This ensures that your library has the ability to implement encapsulation for any field if required in future without breaking the existing codes.If you replace the fields with properties in existing libraries then all the dependent modules using your library also need to be rebuilt.

user1849310
  • 451
  • 6
  • 10
  • "always" is a liitle to hard word. In C# (better than in Java) property has strong position, is (probably without exception) main / method of "binding" in ASP, WPF and others. But nonetheless I can imagine design with field no being property has sense (sometimes) – Jacek Cz Sep 10 '15 at 16:18