Why Won't Anyone Accept Public Fields in C#

Why won't anyone accept public fields in C#?

Because it breaks encapsulation -- this is why most people use accessors heavily. However, if you think it's the right solution for your task, ignore it (meaning the strict encapsulation complaints) and do what's right for your project. Don't let the OO nazis tell you otherwise.

Why aren't all fields/properties/methods public?

The point of using classes is to be able to separate your code into logically related pieces. This makes your code easier to understand and maintain.

For example, if you need to modify code in a class, you can focus more on the way that class functions and less on other parts of your project. However, public members of your class limit this separation somewhat because, if you modify a public member, that can affect other parts of your project.

Keeping as much of your class private as possible (while still usable from your application) maximizes the separation between it and the rest of your application. It makes it easier to think about only the logic in the class you are working on, and it allows you to modify those private members without having to think what other parts of your application might be affected.

Is it possible to not write `public` each time before a field in a block of public fields?

No, there is no way to do that in C#, you have to declare for every field its access way.
In general C# tends limit access by-default, so even if do not write anything, the members will end up like private ones.

Why is using public bad in c#

The use of public vs. private refers to one of the key concepts of object oriented programming: Encapsulation or information hiding.

Encapsulation means that the internal representation of an object is generally hidden from view outside of the object’s definition. Typically, only the object’s own methods can directly inspect or manipulate its fields.

Hiding the internals of the object protects its integrity by preventing users from setting the internal data of the component into an invalid or inconsistent state. A supposed benefit of encapsulation is that it can reduce system complexity, and thus increase robustness, by allowing the developer to limit the inter-dependencies between software components (see Encapsulation on Wikipedia).

In general, you make a method or property public, if it is intended to be used outside of the object, and private, if only is required by your object internally.

Why are public fields faster than properties?

Edit 2:

I had another potential thought here:

You mentioned that you are running on x64. I've tested this same issue on x86, and seen the same performance when using auto-properties vs. fields. However, if you look around on Connect and mailing list/forum posts, there are many references online to the fact that the x64 CLR's JIT is a different code base, and has very different performance characteristics to the x86 JIT. My guess is this is one place where x64 is still lagging behind.

Also, FYI, the struct/method/etc thing fixed in .net 3.5sp1 was on the x86 side, and was the fact that method calls that took structs as a parameter would never be inlined on x86 prior to .net3.5sp1. That's pretty much irrelevant to this discussion on your system.


Edit 3:

Another thing: As to why XNA is using fields. I actually was at the Game Fest where they announced XNA. Rico Mariani gave a talk where he brought up many of the same points that are on his blog. It seems the XNA folks had similar ideas when they developed some of the core objects. See:

http://blogs.msdn.com/ricom/archive/2006/09/07/745085.aspx

Particularly, check out point #2.


As for why automatic properties are better than public fields:

They allow you to change the implementation in v2 of your class, and add logic into the property get/set routines as needed, without changing your interface to your end users. This can have a profound effect on your ability to maintain your library and code over time.

---- From original post - but discovered this wasn't the issue--------

Were you running a release build outside of VS? That can be one explanation for why things aren't being optimized. Often, if you are running in VS, even an optimized release build, the VS host process disables many functions of the JIT. This can cause performance benchmarks to change.

Why do I need a private field that is exposed via public property?

Older versions of C# didn't have automatic properties, so you had to declare your variables that the properties acted upon like in your example. These days, the same code could be expressed as:

public int Age { get; set; }

I think that answers your question. However, if you are asking "why not just have public int Age; and let programmers set the value on the field directly?", then:

First thing to keep in mind is that property accessors are compiled into methods. This means that it has a different ABI from just reading/writing to a class member variable, even though it may syntactically look the same as if you had:

class Fu {
public int Age;
}

So, what this means is that if, at some point down the road, you need to add some notification that the Age field has changed - if you are using properties, you can easily add this notification logic to the property setter without breaking ABI.

public int Age {
get { return age; }
set { age = value; NotifySomeOtherCode (); }
}

If you start off with a public field, then later changing it to a property will change the ABI which is bad for any program(s) that may depend on your assembly. So it's better to start off with properties.

Hopefully I'm making sense...

Cannot access properties of a private field from another class

That is the purpose of private fields - they cannot be accessed from other classes. But making the field public is not the way to go. Usually C# developers wrap the field in a public property, that can have validations o transformations implemented. This is almost what you did, you didn't explicitly make the property public, which is necessary.

The default member visibility is private so you should make your property public:

public class GameData
{
private static int numberOfPlayersInOfflineGame;

public static int NumberOfPlayersInOfflineGame
{
get
{
return numberOfPlayersInOfflineGame;
}
set
{
numberOfPlayersInOfflineGame = value;
}
}
}

But I am against what @Agent_Orange suggests: Do not make your field public as well! That completely defeats the purpose for creating a property. Any code could then bypass potential validations in the property setter to set the numberOfPlayersInOfflineGame to any unexpected value like -100.

As @Jon Skeet notes - if you don't perform any additional tasks in the getter and setter of the property, you could simplify your code by making it an auto-property:

public class GameData
{
public static int NumberOfPlayersInOfflineGame { get; set; }
}

You can now use the property instead of the field both in your class code and outside of the class. If you later decide to add some validations, you can always go back to having a property backed by a private field.

Why ever use fields instead of properties?

Typically, properties need a backing field unless they are simple getter/setter "automatic properties".

So, if you're just doing...

public string Name { get; set; } // automatic property

...you don't need a field, and I agree, no reason to have one.

However, if you're doing...

public string Name
{
get { return _name; }
set
{
if (value = _name) return;
_name = value;
OnPropertyChange("Name");
}
}

...you need that _name backing field.

For private variables that don't require any special get/set logic, it's really a judgment call whether to do a private automatic property or just a field. I usually do a field, then, if I need it to be protected or public, I will change it to an automatic property.

Update

As noted by Yassir, if you use automatic properties, there's still a field lurking behind the scenes, it's just not something you actually have to type out. So, the bottom line is: properties don't store data, they provide access to data. Fields are what actually hold the data. So, you need them even if you can't see them.

Update 2

Regarding your revised question...

is there any time that SomeType someField; is preferable to SomeType SomeProperty { get; set; }?

...one thing that comes to mind: If you have a private field, and (according to convention for private fields) you call it _name, that signals to you and anyone reading your code that you are working directly with private data. If, on the other hand, you make everything a property, and (according to convention for properties) call your private property Name, now you can't just look at the variable and tell that it is private data. So, using only properties strips away some information. I haven't tried working with all properties to gauge whether that is crucial information, but something is definitely lost.

Another thing, more minor, is that public string Name { get; set; } requires more typing (and is a little messier) than private string _name.



Related Topics



Leave a reply



Submit