0

According to the books and websites I have checked when I create a class i want to make sure that the properties are not directly accessible. As such make them Private and then make getters and setters.

As such I have the following for a Card class

    private Suits _suit;
    public Suits Suit { get; set; }
    private Values _value;
    public Values Value { get; set; }

    public Suits Suit { get; set; }
    public Values Value { get; set; }

After I completed the class and did test on it, it states that Suit has 2 references and that _suit is unused. It is the same with Value, it is marked with 8 references and _value is unused. I deleted the two private statements (Creating the second block of code) and the program that I was working on did not change. What is the point of creating a private and then a public if one does not get used. Am I missing something?

  • No point at all, you don't need to define private members. When using automating properties `public string Name { get; set; }` private member will be generated automatically by compiler. – Fabio Sep 13 '19 at 02:36
  • the above example is quite useless, because the below one makes all you need. However, the above code declares a couple of fields (_suit and _value) which are completely independent from the properties, and also private to the class. – Mario Vernari Sep 13 '19 at 02:37
  • https://stackoverflow.com/questions/8817070/is-it-possible-to-access-backing-fields-behind-auto-implemented-properties may be worth a read. – mjwills Sep 13 '19 at 03:49
  • You are mixing fields and properties, please [read about difference](https://stackoverflow.com/q/295104/1997232) and about [auto-properties](https://stackoverflow.com/q/6001917/1997232). – Sinatr Sep 13 '19 at 07:21

2 Answers2

2

Your auto-implemented properties don't reference your fields at all. They have their own auto-generated backing fields that are separate from your fields. This is why deleting your fields has no effect on your properties.

Auto-implemented properties are only encapsulated insofar that you access the properties directly, and not their auto-generated fields. So generally speaking, you're still allowing them to be accessed directly, kind of. What you want to accomplish with properties really depends on how you want your data to be able to be accessed. If you want them to be read-only by callers but writable within the class, give them private setters:

public Suits Suit { get; private set; }
public Values Value { get; private set; }

If you don't want them to be writable after each time the class is initialized, leave the setters out entirely:

public Suits Suit { get; }
public Values Value { get; }

(Also, since these appear to be enum properties, having no setter makes them effectively immutable.)

BoltClock
  • 630,065
  • 150
  • 1,295
  • 1,284
2

The syntax you have for the public ones is that of auto-implemented properties. As commented above, the compiler will automatically turn such properties into get- and set- methods that access a private backing field.

This syntax wasn't available in the original language spec, so there are texts that will describe the use of backing fields as necessary. However, your original source needs to be a little different to actually use them:

private Values _value;
public Values Value
{
    get { return _value; }
    set { _value = value; }
}

This is functionally identical to what you get with the { get; set; } syntax; your code in the first example is being compiled into two auto properties with hidden backing fields, plus two fields you've explicitly declared which the compiler correctly identifies as unused.

There is however a scenario where you will have to use this longhand form: when you want your getter/setter methods to perform additional validation or processing before seting/returning the internal field value; automatic properties don't allow you to inject the additional code.

T2PS
  • 362
  • 1
  • 2
  • 12