This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C#: Public Fields versus Automatic Properties
I read properties in C# are declared or used to provide access of private members to others. In that case, when we are declaring public members, do we still have to declare properties for them.
In the following example, they have declared properties for public members. I don't know why ?
class Customer
{
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; }
}
thanks!
This article gives you a good overview to properties and its overuse
http://www.codinghorror.com/blog/2006/08/properties-vs-public-variables.html
Using properties instead of public fields allows non-breaking changes in how these properties are implemented in the next release - with public fields any change is breaking.
For example you could change the implementation of TotalPurchases to perform a calculation instead of returning the value of a backing field directly. From the point of view of the consumer of the class this change is non-breaking and does not affect how your application works.
public double TotalPurchases
{
get
{
return CalculatePurchases();
}
}
So first of all, properties in C# are declared for many reasons, and it's not about being private at all.
You can, for example, make the getter public and the setter private:
public double TotalPurchases
{
get;
private set;
}
Also, for some frameworks backed up by reflection, they look for properties and not fields.
In this case, properties are a must, even if it looks useless when nothing is done in the getter/setter.
Related
This question already has answers here:
Property hiding and reflection (C#)
(3 answers)
Closed 4 years ago.
I'm working on a custom serializer and my edge case tests revealed an interesting issue: Type.GetProperties method does not return reintroduced properties from the base class of the same signature. While this is expected for overridden properties, I have to serialize non-virtual base properties.
Consider the following example:
public class Base
{
public int NonvirtualProperty { get; set; } // this property is "lost"
public virtual int VirtualProperty { get; set; }
public int BaseOnlyProperty { get; set; }
}
public class Derived : Base
{
public int NonvirtualProperty { get; set; }
public override int VirtualProperty { get; set; }
public int DerivedOnlyProperty { get; set; }
}
The test below demonstrates the issue:
foreach (var p in typeof(Derived).GetProperties(BindingFlags.Public | BindingFlags.Instance))
Console.WriteLine($"{p.DeclaringType.Name}.{p.Name}");
// Derived.NonvirtualProperty
// Derived.VirtualProperty
// Derived.DerivedOnlyProperty
// Base.BaseOnlyProperty
I would expect also Base.NonvirtualProperty in the result.
Note: For fields and methods everything works as expected. This is especially interesting for methods because they also can be virtual.
Note 2: If property types are different in Base and Derived the base property appears in the result.
What would be the best and most efficient solution?
My ideas so far (both of them seem too ugly and overcomplicated for handling such an edge case):
Maybe I could obtain properties of each levels by DeclaredOnly binding flag and somehow detect if they are either non-virtual ones or the most derived properties of virtual ones. Is there a clean way to do that?
Or I could query the methods instead, and check if the returned get_*/set_* methods are really properties.
Imho there is no way to get hidden base properties by just reflecting the derived type. Traversing up the inheritance chain should do the trick.
EDIT: The question seems quite similar to Property hiding and reflection (C#)
There is also a nice example on how to do that traversal with not much Code, see https://stackoverflow.com/a/2715286/7895292
Thats because the Derived.NonvirtualProperty hides the Base.NonvirtualProperty. Like the compiler will say. It will suggests "use the new keyword if hiding was intended"
The prove that it is not directly accessible:
var d = new Derived();
var b = (Base)d;
b.NonvirtualProperty =10;
Console.WriteLine($"{d.NonvirtualProperty}");
Gives 0
A simple example.
alt text http://img19.imageshack.us/img19/1854/51445300.jpg
A have a class TDMReader which is a buldier of TDMFile objects and I am using Auto Implemented Properties f.e.
public string Name
{
get;
set;
}
public Group[] Groups
{
get;
set;
}
What I want to do is to make setter accessible only for TDMReader methods.
In C++ i could have friends methods to access private variables, in Java I could make them in one packet and so access to fields. I have some ideas but with this auto-implemetation is a bit more complicated to do.
Any ideas with a nite solution?:)
Automatic properties have no bearing on this - the same options are available for automatic properties and "manual" properties. You can restrict the access of the setter like this:
// Setter access only to this type and nested types
public string Name { get; private set; }
// Setter access within the assembly
public Group[] Groups { get; internal set; }
etc
... but you can't do it for a single class (unless that class is nested within the declaring type, in which case private would be fine). There's no namespace-restricted access in .NET or C#.
(It's not entirely clear which class the properties are declared in - if they're TdmReader properties, then just make them private. If they're TdmFile properties, you have the problem described above.)
Like this:
public string Name
{
get;
private set;
}
public Group[] Groups
{
get;
private set;
}
By adding the private keyword, the setters will only be accessible by code in the same class. You can also add internal to make it accessible to code in the same project.
Note that exposing an array as a property is extremely poor design.
Instead, you should expose a Collection<Group> or ReadOnlyCollection<Group>, in the System.Collections.ObjectModel namespace.
I'm making a little program that will crawl my hard drive and present a list of file found in a given drive.
My idea is to have a base File class, and implement Picture.cs, Video.cs and Document.cs classes inherited from the File.cs class.
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SharpLibrary_MediaManager
{
public abstract class File
{
public string name;
public string fileType;
public int size;
public DateTime creationDate;
public DateTime modificationDate;
}
}
Should I declare the short hand code for each attribute like this:
public string name { get; set; }
Any guidance will be helpful. Thank you. :)
Edit:
I mean literally replacing this line:
public string name;
with this line:
public string name { get; set; }
First, "attributes" is not the correct terminolgy here. When you declare a member of a class that has get and/or set defined (formally known as "accessors"), you are defining a property. Properties are a convenient way to expose values of private fields because you can add logic to the getting and setting mechanims.
Second, when you declare a member name as you've done via
public string name { get; set; }
the compiler will expand that into the following:
private string _name;
public string name {
get {
return _name;
}
set {
_name = value;
}
}
That is, the compiler will automatically create a backing field for you and define the accessors. These are called "automatic properties" (for the people)1.
Third, you should never2 publically expose fields. So, if you want to expose the string name as part of your public interface it is better to do it as a property. First, it provides better encapsulation. Second, it can be declared virtual and overridden in dervied classes. Third, you can have custom logic. Fourth, you can have different levels of accessibly between the reading and writing mechanisms on properties but you can not on a field.
Fourth, per accepted naming convetions, public properties should be named with CamelCase so that you should prefer Name instead of name.
1: Sorry, bad joke that I've been waiting a long time to make.
2: Almost never.
You're not describing a short hand syntax for a single item but rather 2 completely different types of members. The get/set version creates a C# Property while the non-get/set version creates a field.
// field
public string name;
// property
public string name {get; set;}
So what you're actually asking here is whether or not you should expose name as a field or a property. The answer is almost certainly property.
If your looking to have these properties, which is what adding the { get; set; } will make the variables, then you should declare the set; part of the property as protected.
So it becomes:
public string name { get; protected set; }
The advantage of this is that you are guaranteeing that the property can only be set by either the base class, or any class that inherits the base class.
As others have suggested, following the C# naming conventions is a good idea and also using properties are highly recommended.
Just to be clear, attributes are means to do declarative programming. They are used to decorate methods, classes, etc. msdn link
If you're asking whether to expose properties rather than public fields, then the answer is Yes.
You should also use PascalCase for the property names rather than camelCase:
public string Name { get; set; }
public string FileType { get; set; }
// etc
As Luke says, all things being equal, properties are preferred to fields.
In addition you may want to change the casing of your fields to match standard C# naming conventions.
Lastly, you might want to avoid the "File" name for your class as you'll probably be using the System.IO namespace which also has a File class. Also, System.IO.FileInfo may already include many of the properties you are planning on creating -- there's no point reinventing the wheel.
I believe another advantage of properties over normal public fields will be ability to override them in the derived class.
class Base
{
public virtual int X
{
get
{
Console.Write("Base GET");
return 10;
}
set
{
Console.Write("Base SET");
}
}
}
class Derived : Base
{
public override int X
{
get
{
Console.Write("Derived GET");
return 10;
}
set
{
Console.Write("Derived SET");
}
}
}
Another useful trick that is applicable while using properties is the ability to modify the modifier of the the derived Properties like changing from Public access to Protected.
Hence in many ways its better to use properties in base class to derive.
I have a base type which stores information about a question in a question pool for a system which generates practice question sets to help people study for multiple choice tests. The only information that is stored in it are the answers, the prompt and question number. When I create a practice test, I need to augment the type with some properties to store the answer submitted (the test can be taken in parts), and so I created the following classes:
public class MultipleChoiceQuestion
{
public Int32 Number { get; internal set; }
public String Prompt { get; internal set; }
public MultipleChoiceAnswer[] Choices { get; internal set; }
// constructors, etc...
}
public class PracticeTestQuestion : MultipleChoiceQuestion
{
public MultipleChoiceAnswer AnswerSelected { get; set; }
// is this right?
public PracticeTestQuestion(MultipleChoiceQuestion question)
{
...
}
}
Originally I had the MultipleChoiceQuestion as just a member of PracticeTestQuestion, but it added a lot of extra dots in my property accessors, and so I changed it to inherit the class as listed above. Currently I am assigning all of the properties line for line in the constructor, and but it feels sort of cumbersome, and I was wondering if there is a better way.
The C# compiler doesn't like upsizing types for good reasons, so my question is what is the best way to go about instantiating my PracticeTestQuestions from their MultipleChoiceQuestion base types?
I would add a constructor to MultipleChoiceQuestion that takes another MultipleChoiceQuestion. If necessary it can assign each of the properties in the constructor, but that's more appropriate, since it has the knowledge of its own properties.
Then in PracticeTestQuestion, you can just do:
public PracticeTestQuestion(MultipleChoiceQuestion question) : base(question) { }
and be done with it.
My first gut reaction is to use a factory to create questions. You ask the factory for a MCQ or a PTQ and it creates the right one.
This is also more extensible to essay questions, true false, etc.
I know this must be a common question, but take a look:
Here i have a test class:
public class EmployeeClass
{
private int _id;
private string _name;
private double _salary;
public int id
{
get{...}
set{...}
}
public string name
{
get{...}
set{...}
}
//and so on
}
The question is: for me, it doesnt make sense to have public properties matching ALL private fields.
What is the approach to limit the access to itens of the class?
At the time of initialization do i access the fields directly, as in:
public EmployeeClass(int id, string name, double salary)
{
_id = id;
_name = name;
_salary = salary;
}
AND MAKE ALL (at least the ones that must have some sort of immutability) readonly?
What's the best approach here?
Thank you for your opinions
There are many attitudes, two of them that helps avoiding getters on the class are:
East oriented code
Getters and Setters are evil
In general (and this is only a tiny taste), it is not recommended to have many public setters on the class.
To answer the question from a language convention point of view, prior to C# 3.0, access to internal data was typically performed by declaring private fields with public properties providing read and/or write accessors:
public class Employee
{
private int _id;
public int Id
{
get { return _id; }
set { _id = this; }
}
}
Note: In .Net, properties are in PascalCase by convention.
While the purpose of properties are to provide encapsulation around accessing an object's internal state, properties are often used merely as a pass through to private field access as a placeholder in the event additional behavior is needed in the access or computation of the state. Because this pattern leads to a lot of verbose and repetitive coding, Microsoft introduced the Auto-Implemented Properties feature in C# 3.0. Auto properties allow the developer to declare properties which are automatically backed by a private variable:
public class Employee
{
public int Id { get; set; }
}
Eric Lippert has a great series on the different kinds of immutability in c#. He's also got some examples for how to implement the different kinds of immutability.
What he calls "write-once immutability" is the kind where initialization is done in the constructor of the class and all fields are marked as private readonly fields.