Do unassigned properties take up memory in a class? - c#

This might be a bit of a noob question, but I need to ask it anyway. Consider the following two classes
public class Book{
public string Title;
public string Author;
public string ISBN;
public DateTime Published;
public string Description;
public string Genre;
public float Price
public int Pages;
public Book(){
}
}
public class BookStub{
public string Title;
public string Author;
public BookStub(){
}
}
If I create an instance of each class in the following way
Book a = new Book{
Title = "Do Androids Dream of Electric Sheep?",
Author = "Philip K. Dick"
};
BookStub b = new BookStub{
Title = "Do Androids Dream of Electric Sheep?",
Author = "Philip K. Dick"
};
Do both of these instances take up the same amount of memory? Or does the first one take up more?

Instances of the Book class will consume more memory than instances of the BookStub class because the memory required for all member variables is allocated when an object is first created.
This is necessary because at any time you could write
a.Price = 12.74F;
to set the value of the Price field. If the memory had not been allocated, this code would fail.
Such failure is not possible for object b of type BookStub, because it has no Price field. The compiler would easily detect that error.
So, to answer your question explicitly: yes, unassigned properties still consume memory for each instance of a class. They are simply initialized automatically to their default values.
Note, however, that this is only the case for member variables that must exist for each instance of an object. Both static fields and all types of methods (instance or static) are associated with the class itself and do not consume any additional memory each time a new instance is created. So feel free to add additional methods and static fields without worrying about increasing your memory footprint.

Class Book will consume more memory than BookStub. It doesn't matter that you don't assign to the properties; they still get initialized to the appropriate default values for their types, and those values have to be stored somewhere.

Related

DbContext with and without { get; set; } in C# [duplicate]

In C#, what makes a field different from a property, and when should a field be used instead of a property?
Properties expose fields. Fields should (almost always) be kept private to a class and accessed via get and set properties. Properties provide a level of abstraction allowing you to change the fields while not affecting the external way they are accessed by the things that use your class.
public class MyClass
{
// this is a field. It is private to your class and stores the actual data.
private string _myField;
// this is a property. When accessed it uses the underlying field,
// but only exposes the contract, which will not be affected by the underlying field
public string MyProperty
{
get
{
return _myField;
}
set
{
_myField = value;
}
}
// This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
// used to generate a private field for you
public int AnotherProperty { get; set; }
}
#Kent points out that Properties are not required to encapsulate fields, they could do a calculation on other fields, or serve other purposes.
#GSS points out that you can also do other logic, such as validation, when a property is accessed, another useful feature.
Object orientated programming principles say that, the internal workings of a class should be hidden from the outside world. If you expose a field you're in essence exposing the internal implementation of the class. Therefore we wrap fields with Properties (or methods in Java's case) to give us the ability to change the implementation without breaking code depending on us. Seeing as we can put logic in the Property also allows us to perform validation logic etc if we need it.
C# 3 has the possibly confusing notion of autoproperties. This allows us to simply define the Property and the C#3 compiler will generate the private field for us.
public class Person
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public int Age{get;set;} //AutoProperty generates private field for us
}
An important difference is that interfaces can have properties but not fields. This, to me, underlines that properties should be used to define a class's public interface while fields are meant to be used in the private, internal workings of a class. As a rule I rarely create public fields and similarly I rarely create non-public properties.
I'll give you a couple examples of using properties that might get the gears turning:
Lazy Initialization: If you have a property of an object that's expensive to load, but isn't accessed all that much in normal runs of the code, you can delay its loading via the property. That way, it's just sitting there, but the first time another module tries to call that property, it checks if the underlying field is null - if it is, it goes ahead and loads it, unknown to the calling module. This can greatly speed up object initialization.
Dirty Tracking: Which I actually learned about from my own question here on StackOverflow. When I have a lot of objects which values might have changed during a run, I can use the property to track if they need to be saved back to the database or not. If not a single property of an object has changed, the IsDirty flag won't get tripped, and therefore the saving functionality will skip over it when deciding what needs to get back to the database.
Using Properties, you can raise an event, when the value of the property is changed (aka. PropertyChangedEvent) or before the value is changed to support cancellation.
This is not possible with (direct access to) fields.
public class Person {
private string _name;
public event EventHandler NameChanging;
public event EventHandler NameChanged;
public string Name{
get
{
return _name;
}
set
{
OnNameChanging();
_name = value;
OnNameChanged();
}
}
private void OnNameChanging(){
NameChanging?.Invoke(this,EventArgs.Empty);
}
private void OnNameChanged(){
NameChanged?.Invoke(this,EventArgs.Empty);
}
}
Since many of them have explained with technical pros and cons of Properties and Field, it's time to get into real time examples.
1. Properties allows you to set the read-only access level
Consider the case of dataTable.Rows.Count and dataTable.Columns[i].Caption. They come from the class DataTable and both are public to us. The difference in the access-level to them is that we cannot set value to dataTable.Rows.Count but we can read and write to dataTable.Columns[i].Caption. Is that possible through Field? No!!! This can be done with Properties only.
public class DataTable
{
public class Rows
{
private string _count;
// This Count will be accessable to us but have used only "get" ie, readonly
public int Count
{
get
{
return _count;
}
}
}
public class Columns
{
private string _caption;
// Used both "get" and "set" ie, readable and writable
public string Caption
{
get
{
return _caption;
}
set
{
_caption = value;
}
}
}
}
2. Properties in PropertyGrid
You might have worked with Button in Visual Studio. Its properties are shown in the PropertyGrid like Text,Name etc. When we drag and drop a button, and when we click the properties, it will automatically find the class Button and filters Properties and show that in PropertyGrid (where PropertyGrid won't show Field even though they are public).
public class Button
{
private string _text;
private string _name;
private string _someProperty;
public string Text
{
get
{
return _text;
}
set
{
_text = value;
}
}
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
[Browsable(false)]
public string SomeProperty
{
get
{
return _someProperty;
}
set
{
_someProperty= value;
}
}
In PropertyGrid, the properties Name and Text will be shown, but not SomeProperty. Why??? Because Properties can accept Attributes. It does not show in case where [Browsable(false)] is false.
3. Can execute statements inside Properties
public class Rows
{
private string _count;
public int Count
{
get
{
return CalculateNoOfRows();
}
}
public int CalculateNoOfRows()
{
// Calculation here and finally set the value to _count
return _count;
}
}
4. Only Properties can be used in Binding Source
Binding Source helps us to decrease the number of lines of code. Fields are not accepted by BindingSource. We should use Properties for that.
5. Debugging mode
Consider we are using Field to hold a value. At some point we need to debug and check where the value is getting null for that field. It will be difficult to do where the number of lines of code are more than 1000. In such situations we can use Property and can set debug mode inside Property.
public string Name
{
// Can set debug mode inside get or set
get
{
return _name;
}
set
{
_name = value;
}
}
DIFFERENCES - USES (when and why)
A field is a variable that is declared directly in a class or struct. A class or struct may have instance fields or static fields or both. Generally, you should use fields only for variables that have private or protected accessibility. Data that your class exposes to client code should be provided through methods, properties and indexers. By using these constructs for indirect access to internal fields, you can guard against invalid input values.
A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Properties can be used as if they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily and still helps promote the safety and flexibility of methods.
Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code. A get property accessor is used to return the property value, and a set accessor is used to assign a new value.
Though fields and properties look to be similar to each other, they are 2 completely different language elements.
Fields are the only mechanism how to store data on class level. Fields are conceptually variables at class scope. If you want to store some data to instances of your classes (objects) you need to use fields. There is no other choice. Properties can't store any data even though, it may look they are able to do so. See bellow.
Properties on the other hand never store data. They are just the pairs of methods (get and set) that can be syntactically called in a similar way as fields and in most cases they access (for read or write) fields, which is the source of some confusion. But because property methods are (with some limitations like fixed prototype) regular C# methods they can do whatever regular methods can do. It means they can have 1000 lines of code, they can throw exceptions, call another methods, can be even virtual, abstract or overridden. What makes properties special, is the fact that C# compiler stores some extra metadata into assemblies that can be used to search for specific properties - widely used feature.
Get and set property methods has the following prototypes.
PROPERTY_TYPE get();
void set(PROPERTY_TYPE value);
So it means that properties can be 'emulated' by defining a field and 2 corresponding methods.
class PropertyEmulation
{
private string MSomeValue;
public string GetSomeValue()
{
return(MSomeValue);
}
public void SetSomeValue(string value)
{
MSomeValue=value;
}
}
Such property emulation is typical for programming languages that don't support properties - like standard C++. In C# there you should always prefer properties as the way how to access to your fields.
Because only the fields can store a data, it means that more fields class contains, more memory objects of such class will consume. On the other hand, adding new properties into a class doesn't make objects of such class bigger. Here is the example.
class OneHundredFields
{
public int Field1;
public int Field2;
...
public int Field100;
}
OneHundredFields Instance=new OneHundredFields() // Variable 'Instance' consumes 100*sizeof(int) bytes of memory.
class OneHundredProperties
{
public int Property1
{
get
{
return(1000);
}
set
{
// Empty.
}
}
public int Property2
{
get
{
return(1000);
}
set
{
// Empty.
}
}
...
public int Property100
{
get
{
return(1000);
}
set
{
// Empty.
}
}
}
OneHundredProperties Instance=new OneHundredProperties() // !!!!! Variable 'Instance' consumes 0 bytes of memory. (In fact a some bytes are consumed becasue every object contais some auxiliarity data, but size doesn't depend on number of properties).
Though property methods can do anything, in most cases they serve as a way how to access objects' fields. If you want to make a field accessible to other classes you can do by 2 ways.
Making fields as public - not advisable.
Using properties.
Here is a class using public fields.
class Name
{
public string FullName;
public int YearOfBirth;
public int Age;
}
Name name=new Name();
name.FullName="Tim Anderson";
name.YearOfBirth=1979;
name.Age=40;
While the code is perfectly valid, from design point of view, it has several drawbacks. Because fields can be both read and written, you can't prevent user from writing to fields. You can apply readonly keyword, but in this way, you have to initialize readonly fields only in constructor. What's more, nothing prevents you to store invalid values into your fields.
name.FullName=null;
name.YearOfBirth=2200;
name.Age=-140;
The code is valid, all assignments will be executed though they are illogical. Age has a negative value, YearOfBirth is far in future and doesn't correspond to Age and FullName is null. With fields you can't prevent users of class Name to make such mistakes.
Here is a code with properties that fixes these issues.
class Name
{
private string MFullName="";
private int MYearOfBirth;
public string FullName
{
get
{
return(MFullName);
}
set
{
if (value==null)
{
throw(new InvalidOperationException("Error !"));
}
MFullName=value;
}
}
public int YearOfBirth
{
get
{
return(MYearOfBirth);
}
set
{
if (MYearOfBirth<1900 || MYearOfBirth>DateTime.Now.Year)
{
throw(new InvalidOperationException("Error !"));
}
MYearOfBirth=value;
}
}
public int Age
{
get
{
return(DateTime.Now.Year-MYearOfBirth);
}
}
public string FullNameInUppercase
{
get
{
return(MFullName.ToUpper());
}
}
}
The updated version of class has the following advantages.
FullName and YearOfBirth are checked for invalid values.
Age is not writtable. It's callculated from YearOfBirth and current year.
A new property FullNameInUppercase converts FullName to UPPER CASE. This is a little contrived example of property usage, where properties are commonly used to present field values in the format that is more appropriate for user - for instance using current locale on specific numeric of DateTime format.
Beside this, properties can be defined as virtual or overridden - simply because they are regular .NET methods. The same rules applies for such property methods as for regular methods.
C# also supports indexers which are the properties that have an index parameter in property methods. Here is the example.
class MyList
{
private string[] MBuffer;
public MyList()
{
MBuffer=new string[100];
}
public string this[int Index]
{
get
{
return(MBuffer[Index]);
}
set
{
MBuffer[Index]=value;
}
}
}
MyList List=new MyList();
List[10]="ABC";
Console.WriteLine(List[10]);
Since C# 3.0 allows you to define automatic properties. Here is the example.
class AutoProps
{
public int Value1
{
get;
set;
}
public int Value2
{
get;
set;
}
}
Even though class AutoProps contains only properties (or it looks like), it can store 2 values and size of objects of this class is equal to sizeof(Value1)+sizeof(Value2)=4+4=8 bytes.
The reason for this is simple. When you define an automatic property, C# compiler generates automatic code that contains hidden field and a property with property methods accessing this hidden field. Here is the code compiler produces.
Here is a code generated by the ILSpy from compiled assembly. Class contains generated hidden fields and properties.
internal class AutoProps
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int <Value1>k__BackingField;
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int <Value2>k__BackingField;
public int Value1
{
[CompilerGenerated]
get
{
return <Value1>k__BackingField;
}
[CompilerGenerated]
set
{
<Value1>k__BackingField = value;
}
}
public int Value2
{
[CompilerGenerated]
get
{
return <Value2>k__BackingField;
}
[CompilerGenerated]
set
{
<Value2>k__BackingField = value;
}
}
}
So, as you can see, the compiler still uses the fields to store the values - since fields are the only way how to store values into objects.
So as you can see, though properties and fields have similar usage syntax they are very different concepts. Even if you use automatic properties or events - hidden fields are generated by compiler where the real data are stored.
If you need to make a field value accessible to the outside world (users of your class) don't use public or protected fields. Fields always should be marked as private. Properties allow you to make value checks, formatting, conversions etc. and generally make your code safer, more readable and more extensible for future modifications.
Properties have the primary advantage of allowing you to change the way data on an object is accessed without breaking it's public interface. For example, if you need to add extra validation, or to change a stored field into a calculated you can do so easily if you initially exposed the field as a property. If you just exposed a field directly, then you would have to change the public interface of your class to add the new functionality. That change would break existing clients, requiring them to be recompiled before they could use the new version of your code.
If you write a class library designed for wide consumption (like the .NET Framework, which is used by millions of people), that can be a problem. However, if you are writing a class used internally inside a small code base (say <= 50 K lines), it's really not a big deal, because no one would be adversely affected by your changes. In that case it really just comes down to personal preference.
Properties support asymmetric access, i.e. you can have either a getter and a setter or just one of the two. Similarly properties support individual accessibility for getter/setter. Fields are always symmetric, i.e. you can always both get and set the value. Exception to this is readonly fields which obviously cannot be set after initialization.
Properties may run for a very long time, have side effects, and may even throw exceptions. Fields are fast, with no side effects, and will never throw exceptions. Due to side effects a property may return a different value for each call (as may be the case for DateTime.Now, i.e. DateTime.Now is not always equal to DateTime.Now). Fields always return the same value.
Fields may be used for out / ref parameters, properties may not.
Properties support additional logic – this could be used to implement lazy loading among other things.
Properties support a level of abstraction by encapsulating whatever it means to get/set the value.
Use properties in most / all cases, but try to avoid side effects.
In the background a property is compiled into methods. So a Name property is compiled into get_Name() and set_Name(string value). You can see this if you study the compiled code.
So there is a (very) small performance overhead when using them. Normally you will always use a Property if you expose a field to the outside, and you will often use it internally if you need to do validation of the value.
When you want your private variable(field) to be accessible to object of your class from other classes you need to create properties for those variables.
for example if I have variables named as "id" and "name" which is private
but there might be situation where this variable needed for read/write operation outside of the class. At that situation , property can help me to get that variable to read/write depending upon the get/set defined for the property. A property can be a readonly / writeonly / readwrite both.
here is the demo
class Employee
{
// Private Fields for Employee
private int id;
private string name;
//Property for id variable/field
public int EmployeeId
{
get
{
return id;
}
set
{
id = value;
}
}
//Property for name variable/field
public string EmployeeName
{
get
{
return name;
}
set
{
name = value;
}
}
}
class MyMain
{
public static void Main(string [] args)
{
Employee aEmployee = new Employee();
aEmployee.EmployeeId = 101;
aEmployee.EmployeeName = "Sundaran S";
}
}
The second question here, "when should a field be used instead of a property?", is only briefly touched on in this other answer and kinda this one too, but not really much detail.
In general, all the other answers are spot-on about good design: prefer exposing properties over exposing fields. While you probably won't regularly find yourself saying "wow, imagine how much worse things would be if I had made this a field instead of a property", it's so much more rare to think of a situation where you would say "wow, thank God I used a field here instead of a property."
But there's one advantage that fields have over properties, and that's their ability to be used as "ref" / "out" parameters. Suppose you have a method with the following signature:
public void TransformPoint(ref double x, ref double y);
and suppose that you want to use that method to transform an array created like this:
System.Windows.Point[] points = new Point[1000000];
Initialize(points);
Here's I think the fastest way to do it, since X and Y are properties:
for (int i = 0; i < points.Length; i++)
{
double x = points[i].X;
double y = points[i].Y;
TransformPoint(ref x, ref y);
points[i].X = x;
points[i].Y = y;
}
And that's going to be pretty good! Unless you have measurements that prove otherwise, there's no reason to throw a stink. But I believe it's not technically guaranteed to be as fast as this:
internal struct MyPoint
{
internal double X;
internal double Y;
}
// ...
MyPoint[] points = new MyPoint[1000000];
Initialize(points);
// ...
for (int i = 0; i < points.Length; i++)
{
TransformPoint(ref points[i].X, ref points[i].Y);
}
Doing some measurements myself, the version with fields takes about 61% of the time as the version with properties (.NET 4.6, Windows 7, x64, release mode, no debugger attached). The more expensive the TransformPoint method gets, the less pronounced that the difference becomes. To repeat this yourself, run with the first line commented-out and with it not commented-out.
Even if there were no performance benefits for the above, there are other places where being able to use ref and out parameters might be beneficial, such as when calling the Interlocked or Volatile family of methods. Note: In case this is new to you, Volatile is basically a way to get at the same behavior provided by the volatile keyword. As such, like volatile, it doesn't magically solve all thread-safety woes like its name suggests that it might.
I definitely don't want to seem like I'm advocating that you go "oh, I should start exposing fields instead of properties." The point is that if you need to regularly use these members in calls that take "ref" or "out" parameters, especially on something that might be a simple value type that's unlikely to ever need any of the value-added elements of properties, an argument can be made.
Also, properties allow you to use logic when setting values.
So you can say you only want to set a value to an integer field, if the value is greater than x, otherwise throw an exception.
Really useful feature.
(This should really be a comment, but I can't post a comment, so please excuse if it is not appropriate as a post).
I once worked at a place where the recommended practice was to use public fields instead of properties when the equivalent property def would just have been accessing a field, as in :
get { return _afield; }
set { _afield = value; }
Their reasoning was that the public field could be converted into a property later in future if required. It seemed a little strange to me at the time. Judging by these posts, it looks like not many here would agree either. What might you have said to try to change things ?
Edit : I should add that all of the code base at this place was compiled at the same time, so they might have thought that changing the public interface of classes (by changing a public field to a property) was not a problem.
Technically, i don't think that there is a difference, because properties are just wrappers around fields created by the user or automatically created by the compiler.The purpose of properties is to enforce encapsuation and to offer a lightweight method-like feature.
It's just a bad practice to declare fields as public, but it does not have any issues.
Fields are ordinary member variables or member instances of a class. Properties are an abstraction to get and set their values. Properties are also called accessors because they offer a way to change and retrieve a field if you expose a field in the class as private. Generally, you should declare your member variables private, then declare or define properties for them.
class SomeClass
{
int numbera; //Field
//Property
public static int numbera { get; set;}
}
If you are going to use thread primitives you are forced to use fields. Properties can break your threaded code. Apart from that, what cory said is correct.
My design of a field is that a field needs to be modified only by its parent, hence the class. Result the variable becomes private, then to be able to give the right to read the classes / methods outside I go through the system of property with only the Get. The field is then retrieved by the property and read-only! If you want to modify it you have to go through methods (for example the constructor) and I find that thanks to this way of making you secure, we have better control over our code because we "flange". One could very well always put everything in public so every possible case, the notion of variables / methods / classes etc ... in my opinion is just an aid to the development, maintenance of the code. For example, if a person resumes a code with public fields, he can do anything and therefore things "illogical" in relation to the objective, the logic of why the code was written. It's my point of view.
When i use a classic model private field / public readonly properties,for 10 privates fields i should write 10 publics properties! The code can be really big faster. I discover the private setter and now i only use public properties with a private setter.
The setter create in background a private field.
That why my old classic programming style was:
public class MyClass
{
private int _id;
public int ID { get { return _id; } }
public MyClass(int id)
{
_id = id;
}
}
My new programming style:
public class MyClass
{
public int ID { get; private set; }
public MyClass(int id)
{
ID = id;
}
}
Basic and general difference is:
Fields
ALWAYS give both get and set access
CAN NOT cause side effects (throwing exceptions, calling methods, changing fields except the one being got/set, etc)
Properties
NOT ALWAYS give both get and set access
CAN cause side effects
Properties encapsulate fields, thus enabling you to perform additional processing on the value to be set or retrieved. It is typically overkill to use properties if you will not be doing any pre- or postprocessing on the field value.
IMO, Properties are just the "SetXXX()" "GetXXX()" functions/methods/interfaces pairs we used before, but they are more concise and elegant.
Traditionally private fields are set via getter and setter methods. For the sake of less code you can use properties to set fields instead.
when you have a class which is "Car". The properties are color,shape..
Where as fields are variables defined within the scope of a class.
From Wikipedia -- Object-oriented programming:
Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which are data structures that contain data, in the form of fields, often known as attributes; and code, in the form of procedures, often known as methods. (emphasis added)
Properties are actually part of an object's behavior, but are designed to give consumers of the object the illusion/abstraction of working with the object's data.
Properties are special kind of class member, In properties we use a predefined Set or Get method.They use accessors through which we can read, written or change the values of the private fields.
For example, let us take a class named Employee, with private fields for name, age and Employee_Id. We cannot access these fields from outside the class , but we can access these private fields through properties.
Why do we use properties?
Making the class field public & exposing it is risky, as you will not have control what gets assigned & returned.
To understand this clearly with an example lets take a student class who have ID, passmark, name. Now in this example some problem with public field
ID should not be -ve.
Name can not be set to null
Pass mark should be read only.
If student name is missing No Name should be return.
To remove this problem We use Get and set method.
// A simple example
public class student
{
public int ID;
public int passmark;
public string name;
}
public class Program
{
public static void Main(string[] args)
{
student s1 = new student();
s1.ID = -101; // here ID can't be -ve
s1.Name = null ; // here Name can't be null
}
}
Now we take an example of get and set method
public class student
{
private int _ID;
private int _passmark;
private string_name ;
// for id property
public void SetID(int ID)
{
if(ID<=0)
{
throw new exception("student ID should be greater then 0");
}
this._ID = ID;
}
public int getID()
{
return_ID;
}
}
public class programme
{
public static void main()
{
student s1 = new student ();
s1.SetID(101);
}
// Like this we also can use for Name property
public void SetName(string Name)
{
if(string.IsNullOrEmpty(Name))
{
throw new exeception("name can not be null");
}
this._Name = Name;
}
public string GetName()
{
if( string.IsNullOrEmpty(This.Name))
{
return "No Name";
}
else
{
return this._name;
}
}
// Like this we also can use for Passmark property
public int Getpassmark()
{
return this._passmark;
}
}
Additional info:
By default, get and set accessors are as accessible as the property itself.
You can control/restrict accessor accessibility individually (for get and set) by applying more restrictive access modifiers on them.
Example:
public string Name
{
get
{
return name;
}
protected set
{
name = value;
}
}
Here get is still publicly accessed (as the property is public), but set is protected (a more restricted access specifier).
Think about it : You have a room and a door to enter this room. If you want to check how who is coming in and secure your room, then you should use properties otherwise they won't be any door and every one easily come in w/o any regulation
class Room {
public string sectionOne;
public string sectionTwo;
}
Room r = new Room();
r.sectionOne = "enter";
People is getting in to sectionOne pretty easily, there wasn't any checking
class Room
{
private string sectionOne;
private string sectionTwo;
public string SectionOne
{
get
{
return sectionOne;
}
set
{
sectionOne = Check(value);
}
}
}
Room r = new Room();
r.SectionOne = "enter";
Now you checked the person and know about whether he has something evil with him
Fields are the variables in classes. Fields are the data which you can encapsulate through the use of access modifiers.
Properties are similar to Fields in that they define states and the data associated with an object.
Unlike a field a property has a special syntax that controls how a person reads the data and writes the data, these are known as the get and set operators. The set logic can often be used to do validation.
Properties are used to expose field. They use accessors(set, get) through which the values of the private fields can be read, written or manipulated.
Properties do not name the storage locations. Instead, they have accessors that read, write, or compute their values.
Using properties we can set validation on the type of data that is set on a field.
For example we have private integer field age on that we should allow positive values since age cannot be negative.
We can do this in two ways using getter and setters and using property.
Using Getter and Setter
// field
private int _age;
// setter
public void set(int age){
if (age <=0)
throw new Exception();
this._age = age;
}
// getter
public int get (){
return this._age;
}
Now using property we can do the same thing. In the value is a key word
private int _age;
public int Age{
get{
return this._age;
}
set{
if (value <= 0)
throw new Exception()
}
}
Auto Implemented property if we don't logic in get and set accessors we can use auto implemented property.
When use auto-implemented property compiles creates a private, anonymous field that can only be accessed through get and set accessors.
public int Age{get;set;}
Abstract Properties
An abstract class may have an abstract property, which should be implemented in the derived class
public abstract class Person
{
public abstract string Name
{
get;
set;
}
public abstract int Age
{
get;
set;
}
}
// overriden something like this
// Declare a Name property of type string:
public override string Name
{
get
{
return name;
}
set
{
name = value;
}
}
We can privately set a property
In this we can privately set the auto property(set with in the class)
public int MyProperty
{
get; private set;
}
You can achieve same with this code. In this property set feature is not available as we have to set value to field directly.
private int myProperty;
public int MyProperty
{
get { return myProperty; }
}

C# : assign data to properties via constructor vs. instantiating

Supposing I have an Album class :
public class Album
{
public string Name {get; set;}
public string Artist {get; set;}
public int Year {get; set;}
public Album()
{ }
public Album(string name, string artist, int year)
{
this.Name = name;
this.Artist = artist;
this.Year = year;
}
}
When I want to assign data to an object of type Album, what is the difference between the next 2 approaches :
Via Constructor
var albumData = new Album("Albumius", "Artistus", 2013);
or when instantiating
var albumData = new Album
{
Name = "Albumius",
Artist = "Artistus",
Year = 2013
};
Both approaches call a constructor, they just call different ones. This code:
var albumData = new Album
{
Name = "Albumius",
Artist = "Artistus",
Year = 2013
};
is syntactic shorthand for this equivalent code:
var albumData = new Album();
albumData.Name = "Albumius";
albumData.Artist = "Artistus";
albumData.Year = 2013;
The two are almost identical after compilation (close enough for nearly all intents and purposes). So if the parameterless constructor wasn't public:
public Album() { }
then you wouldn't be able to use the object initializer at all anyway. So the main question isn't which to use when initializing the object, but which constructor(s) the object exposes in the first place. If the object exposes two constructors (like the one in your example), then one can assume that both ways are equally valid for constructing an object.
Sometimes objects don't expose parameterless constructors because they require certain values for construction. Though in cases like that you can still use the initializer syntax for other values. For example, suppose you have these constructors on your object:
private Album() { }
public Album(string name)
{
this.Name = name;
}
Since the parameterless constructor is private, you can't use that. But you can use the other one and still make use of the initializer syntax:
var albumData = new Album("Albumius")
{
Artist = "Artistus",
Year = 2013
};
The post-compilation result would then be identical to:
var albumData = new Album("Albumius");
albumData.Artist = "Artistus";
albumData.Year = 2013;
Object initializers are cool because they allow you to set up a class inline. The tradeoff is that your class cannot be immutable. Consider:
public class Album
{
// Note that we make the setter 'private'
public string Name { get; private set; }
public string Artist { get; private set; }
public int Year { get; private set; }
public Album(string name, string artist, int year)
{
this.Name = name;
this.Artist = artist;
this.Year = year;
}
}
If the class is defined this way, it means that there isn't really an easy way to modify the contents of the class after it has been constructed. Immutability has benefits. When something is immutable, it is MUCH easier to determine that it's correct. After all, if it can't be modified after construction, then there is no way for it to ever be 'wrong' (once you've determined that it's structure is correct). When you create anonymous classes, such as:
new {
Name = "Some Name",
Artist = "Some Artist",
Year = 1994
};
the compiler will automatically create an immutable class (that is, anonymous classes cannot be modified after construction), because immutability is just that useful. Most C++/Java style guides often encourage making members const(C++) or final (Java) for just this reason. Bigger applications are just much easier to verify when there are fewer moving parts.
That all being said, there are situations when you want to be able quickly modify the structure of your class. Let's say I have a tool that I want to set up:
public void Configure(ConfigurationSetup setup);
and I have a class that has a number of members such as:
class ConfigurationSetup {
public String Name { get; set; }
public String Location { get; set; }
public Int32 Size { get; set; }
public DateTime Time { get; set; }
// ... and some other configuration stuff...
}
Using object initializer syntax is useful when I want to configure some combination of properties, but not neccesarily all of them at once. For example if I just want to configure the Name and Location, I can just do:
ConfigurationSetup setup = new ConfigurationSetup {
Name = "Some Name",
Location = "San Jose"
};
and this allows me to set up some combination without having to define a new constructor for every possibly permutation.
On the whole, I would argue that making your classes immutable will save you a great deal of development time in the long run, but having object initializer syntax makes setting up certain configuration permutations much easier.
Second approach is object initializer in C#
Object initializers let you assign values to any accessible fields or
properties of an object at creation time without having to
explicitly invoke a constructor.
The first approach
var albumData = new Album("Albumius", "Artistus", 2013);
explicitly calls the constructor, whereas in second approach constructor call is implicit. With object initializer you can leave out some properties as well. Like:
var albumData = new Album
{
Name = "Albumius",
};
Object initializer would translate into something like:
var albumData;
var temp = new Album();
temp.Name = "Albumius";
temp.Artist = "Artistus";
temp.Year = 2013;
albumData = temp;
Why it uses a temporary object (in debug mode) is answered here by Jon Skeet.
As far as advantages for both approaches are concerned, IMO, object initializer would be easier to use specially if you don't want to initialize all the fields. As far as performance difference is concerned, I don't think there would any since object initializer calls the parameter less constructor and then assign the properties. Even if there is going to be performance difference it should be negligible.

A good design to pack parameters?

I have an object that takes plenty of parameters to its constructor (from 9 to 13 depending on use).
I want to avoid the ugliness of new MyObject(param1, param2, param3 ... param13).
My first attempt was to create a class MyObjectParams with properties with public getters and setters, it gives something like that :
var objectParams = new MyObjectParams
{
Param1 = ...,
Param2 = ...,
...
};
I see some big projects like SlimDX for their PresentParameters use this design. It looks better. But the class is not immutable.
I'd like my MyObjectParams to be immutable while still using a clean construction style. This is how it would look like with an immutable class :
var objectParams = new MyObjectParams
(
param1,
param2,
...
);
Note: it's just the long constructor line broken into several, so it's cleaner but still not as readable as initializers.
I was thinking of using named parameters to get both an immutable class and a more or less clean code, but I'm not sure whether this actually is a good idea:
var objectParams = new MyObjectParams
(
param1: ...,
param2: ...,
...
);
Should I use named parameters? Can you think of a better approach to solve this problem?
Edited regarding an answer below: unfortunately, I don't really think the design is bad. The 9 parameters really are required and remain constant throughout the entire life of the object. I cannot provide a default value for them as it is completely usage-dependant.
Have you looked into designing a solution in which you wouldn't need this amount of parameters? Having a lot of parameters makes the code very tightly coupled which reduces maintainability. Maybe you can redesign a small amount of code to a design which better separates the responsibilities of the class?
I really like the way The Zen of Python says a few things:
Simple is better than complex.
Complex is better than complicated.
[...]
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
I believe that having a dedicated Options class of some kind with the exhaustive list of all possible parameters is a good idea. Allow your MyObject constructor to require an Options instance, and then store a reference to the instance as a field on MyObject and refer to its getters/setters. (Storing the reference will be much superior to trying to parse the options and transfer their values to the MyObject instance. Now that would be messy.) With all data access delegated to the Options class, you will have successfully encapsulated the object's configuration, and you've designed a simple API for option access as the same time.
If Options has no reason to be publicly accessible, make it a private class definition and then you're free to maintain changes to Options logic without modifying MyObject. I believe that is a fair solution to you as the developer, and doesn't commit atrocities.
The constructor could have only a small number of parameters, the ones required for proper object initialization. You could then have a number of properties that can be set after the object has been constructed. You can set default values for those properties in the constructor and the client can set the ones he/she requires.
class Person
{
public Person(string name, int age)
{
Name = name;
Age = age;
Address = "Unknown";
Email = "Unknown";
}
public string Name {get; private set;}
public int Age {get; private set;}
public string Email {get; set;}
public string Address {get; set;}
}
Person p = new Person("John Doe", 30);
p.Email = "john.doe#example.org";
You could use the builder pattern to construct an immutable object.
public sealed class ComplexObject
{
public int PropA { get; private set; }
public string PropB { get; private set; }
public sealed class Builder
{
int _propA;
string _propB;
public Builder SetPropA(int propA)
{
// validate
_propA = propA;
return this;
}
public Builder SetPropB(string propB)
{
// validate
_propB = propB;
return this;
}
public CustomObject ToCustomObject()
{
return new CustomObject
{
PropA = _propA,
PropB = _propB
};
}
}
}
Usage
var custom =
new CustomObject.Builder()
.SetPropA(1)
.SetPropB("Test")
.ToCustomObject();
Final Thoughts
Despite my previous suggestion I am in no way against using named parameters if they are available.

Using static objects

My understanding is any method which does not modify state of the constaining class is a prime candidate to be made static because it does not touch the instance. An instance would be that containing class's data (fields/properties) so if I had a person class with a property called Name (and just that one property), and I am not modifying that property then my class can be set as static, but of course, but the function could be working with another object. Is this the right thing to look for when checking if a method should be made static?
Static variables are described as global variables, but what is the difference of this to any publicly variable? All the variables are in the server's memory and will be lost in a reboot etc. And then use this variable to hold expensive-to-get data (eg running stored procedures in a loop etc).
Thanks
My understanding is any method which does not modify state of the constaining class is a prime candidate to be made static because it does not touch the instance.
I wouldn't say it's a prime candidate, but rather just a candidate. Personally, I think methods should be made static if the API would suggest that it should be static from a logical, algorithmic standpoint. Technically, any method which doesn't change state can be static, but I don't believe it necessarily should be static.
and I am not modifying that property then my class can be set as static, but of course, but the function could be working with another object.
You can only set your class as static in C# if it has absolutely no instance variables. "Instances" of a static class don't exist (and cannot exist), nor can non-static members.
Now - for what I think you're really after...
The difference between a static variable and a non-static variable has to do with how it's accessed. When you define a static field on a class, you're defining a field that will always have a single instance (instance of the field) tied to the class itself. When you define a non-static, normal field, on the other hand, you will potentially have many instances of your field, each residing within one instance of your class.
This is why static variables are often described as global - anything that has access to the class has access to it's one copy of the static variable (provided its publicly accessible). However, non-static fields are different - you need to have a reference to the specific instance of the class in order to read or write to a non-static member.
.
My understanding is any method which
does not modify state of the
constaining [sic] class is a prime candidate
to be made static because it does not
touch the instance.
I don't think this is the right way to think of static vs. non-static. Rather, any method which is not related to the state of a class instance can be static. A name is obviously associated with a particular person, so a Name field on a Person class should almost certainly not be static. Otherwise, you could end up with a scenario like this:
public class Person {
public static string Name { get; set; }
public Person(string name) { Name = name; }
public override string ToString() {
return Name;
}
}
Person dan = new Person("Dan";
Person john = new Person("John";
// outputs "John"
Console.WriteLine(john);
// outputs "John" again, since Dan doesn't have a name property all his own
// (and neither does John, for that matter)
Console.WriteLine(dan);
EDIT: Now, suppose we have a property such as House which can belong to not one but several people. blade asks: "How would this be modeled in code - static?"
My answer: NO, for the same reason already mentioned above. Suppose I've fixed the problem above by making the Name property non-static. Then I introduce a new static House property. Now I have a situation like this:
public class Person {
public string Name { get; set; }
public static House House { get; set; }
public Person(string name, House house) {
Name = name;
House = house;
}
public override string ToString() {
return String.Concat(Name, ", ", House);
}
}
public class House {
public double SquareFootage { get; set; }
public House(double sqft) { SquareFootage = sqft; }
public override string ToString() {
return String.Format("House - {0} sq. ft.", SquareFootage);
}
}
House danAndKatsHouse = new House(1000.0);
House johnsHouse = new House(2000.0);
Person dan = new Person("Dan", danAndKatsHouse);
// outputs "Dan, House - 1000 sq. ft." as expected
Console.WriteLine(dan);
Person kat = new Person("Kat", danAndKatsHouse);
// outputs "Kat, House - 1000 sq. ft.", again as expected
Console.WriteLine(kat);
Person john = new Person("John", johnsHouse);
// outputs "John, House - 2000 sq. ft.", so far so good...
Console.WriteLine(john);
// but what's this? suddenly dan and kat's house has changed?
// outputs "Dan, House - 2000 sq. ft."
Console.WriteLine(dan);
There's a difference between multiple objects of one class sharing the same object and ALL objects of that class sharing the same object. In the latter case, a static property makes sense; otherwise, it does not.
There are a few ways off the top of my head to deal with this scenario. They are:
1. Make the House property non-static
It might seem strange, but you can always just make the House property non-static and you won't ever have to worry about the problem above. Furthermore, assuming you actually do assign the same House object to each Person who shares it, making a change to the House through one Person object will actually achieve the desired effect:
House danAndKatsHouse = new House(1000.0);
// (after making Person.House property non-static)
Person dan = new Person("Dan", danAndKatsHouse);
Person kat = new Person("Kat", danAndKatsHouse);
dan.House.SquareFootage = 1500.0;
// outputs "1500"
Console.WriteLine(kat.House.SquareFootage);
This could actually be a problem, however, if you accidentally assign the same House to two people with the intention of them actually having two different Houses:
House smallerHouse = new House(1000.0);
House biggerHouse = new House(2000.0);
Person dan = new Person("Dan", smallerHouse);
Person john = new Person("John", biggerHouse);
Person bill = new Person("Bill", smallerHouse);
bill.House.SquareFootage = 1250.0;
// yikes, Dan's house just changed...
Console.WriteLine(dan);
2. Use a database
The fact is that the notion of making a house a property of a person is somewhat a forced concept to begin with. A person may move out of their house, different people may move in, etc. Really a relationship exists between the two, which makes using a database an appropriate solution.
Using this approach, what you'd do is have a Persons table, a Houses table, and a third table (maybe PersonHouses) containing id pairs from the other two tables to represent, I guess, home ownership.
If you don't have a full-blown database at your disposal, you can achieve effectively the same result (in .NET) using a System.Data.DataSet and its collection of System.Data.DataTable objects in your code. However, in any scenario where you are translating rows of a database (or DataTable) to objects and then back again, you do need to be aware of impedence mismatch. Basically, whatever meticulous precautions you take in your code to encapsulate your data are out the window once that data is in the database, ready to be modified by anyone with sufficient permissions.
3. Use dictionaries
Another approach, similar to using a database but a bit more work (and I think some programmers who've gone the DataSet route shudder at the thought of this), is to use dictionaries to keep track of your Person and House objects. The quickest way to implement this approach would be to have a Dictionary<int, Person> and a Dictionary<int, House>, and assign each Person a HouseId property:
public class Person {
public int Id { get; private set; }
public string Name { get; set; }
public int HouseId { get; set; }
private static int LastIdValue { get; set; }
private static Dictionary<int, Person> People { get; set; }
static Person() {
LastIdValue = 0;
People = new Dictionary<int, Person>();
}
// make the constructor private to disallow direct instantiation
private Person(int id, string name, int houseId) {
Id = id;
Name = name;
HouseId = houseId;
}
// only permit construction through this function, which inserts
// the new Person into the static dictionary before returning it
static public Person NewPerson(string name, int houseId) {
Person p = new Person(LastIdValue++, name, houseId);
People.Add(p.Id, p);
return p;
}
static public Person getPersonById(int id) {
Person p = null;
return People.TryGetValue(id, out p) ? p : null;
}
}
public class House {
public int Id { get; private set; }
public int SquareFootage { get; set; }
private static int LastIdValue { get; set; }
private static Dictionary<int, House> Houses { get; set; }
static House() {
LastIdValue = 0;
Houses = new Dictionary<int, House>();
}
// make the constructor private to disallow direct instantiation
private House(int id, int sqft) {
Id = id;
SquareFootage = sqft;
}
// only permit construction through this function, which inserts
// the new House into the static dictionary before returning it
static public House NewHouse(int sqft) {
House h = new House(LastIdValue++, sqft);
Houses.Add(h.Id, h);
return h;
}
static public House getHouseById(int id) {
House h = null;
return Houses.TryGetValue(id, out h) ? h : null;
}
}
House firstHouse = House.NewHouse(1000.0);
House secondHouse = House.NewHouse(2000.0);
Person dan = Person.NewPerson("Dan", firstHouse.Id);
Person kat = Person.NewPerson("Kat", firstHouse.Id);
Person john = Person.NewPerson("John", secondHouse.Id);
House dansHouse = House.getHouseById(dan.HouseId);
House katsHouse = House.getHouseById(kat.HouseId);
// this prints
if (katsHouse == dansHouse) { Console.WriteLine("Dan and Kat live in the same house."); }
// this also prints
if (dansHouse == firstHouse) { Console.WriteLine("Dan and Kat live in the first house."); }
// this does not print
if (dansHouse == secondHouse) { Console.WriteLine("Dan and Kat live in the second house."); }
This way, all your data encapsulation still holds. However, if you ever need your data to persist between instances of your code running, then you need to serialize your dictionaries in some file format (most likely XML), which could then be edited by anyone with sufficient privileges, and then you're back to the impedence mismatch problem of using a database all over again.
In light of the advantages and disadvantages of each approach, I think what actually makes the most sense -- and makes your life easiest -- is to simply make House a non-static property. This is assuming you don't have tons and tons of Person and House objects to keep track of.
" if I had a person class with a
property called Name (and just that
one property), and I am not modifying
that property then my class can be set
as static"
That is not correct. A person class is almost certainly a domain entity. It is conceivable you might want to have a static method on a Person entity, but I haven't ever come across one. In your example, you would have a private setter for your 'Name' property.
The static-ness of anything should model your domain, rather than being a language implementaion detail.
There are no true globl variables in C#, in the sense that that term is used in other languages like C. The difference between a static object and a global object is that a static object has permissions that are relative to the class in which it is defined. This is a very good thing, because you can create private static members that are only accessible to member of one class. The big problem with the abuse of global variables is the many depenencies to a single global variable that can evolve across a large colleciton of modules. Private static object avoid this problem.
One big problem with static objects is that they are not thread safe. In order to declare a thread safe static object, you must use the ThreadStatic attribute and provide a way for the object to be initialized on first access. You should do this for all multi-threaded environents e.g. ASP.NET, and any general purpose library that might run in multi-threaded environment. Heck, just always do this and you won't be sorry!
If you have a Person class with a static field name:
public class Person {
public static string Name { get; set; }
}
then you can only ever have one name. You can not have a list of persons with different names. Static can be seen as "Unique" in the way that it's value is global. This can be a trap in ASP.net applications by the way, because static applies through the entire application, which means to all users.
Static variables are rather rare and used for data that is really not part of a specific instance of the class. Or to return specific instances.
For example, Guid.Empty is a static field that returns a Guid that has all Bits set to 0.
A good example is System.Drawing.Color. Color has instance-specific variables, for example R,G,B and Alpha, but you have static fields like Color.Black which returns a Black color.

Is it OK to use a public variable in C# if it is readonly?

Is there some internal difference between the C# syntactic sugar way of making properties:
public string FirstName { get; set; }
and just making public variables like this:
public string LastName;
I assume the first way is preferred and the second to be avoided. However, I often see this type of readonly property being used which is a form of the second type above:
public readonly string InternalCode;
Is this a best-practice way to create readonly property?
using System;
namespace TestProps
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
customer.FirstName = "Jim";
customer.LastName = "Smith";
customer.Show();
}
}
class Customer
{
public string FirstName { get; set; } //prefered
public string LastName; //avoid
public readonly string InternalCode; //???
public Customer()
{
InternalCode = "234729834723984";
}
public void Show()
{
Console.WriteLine("{0}, {1} ({2})", LastName, FirstName, InternalCode);
Console.ReadLine();
}
}
}
Since he didn't answer (yet) and no one else referenced this yet: There is a great article on this topic by Jon Skeet amending his book C# in depth (give credits to Jon):
Why Properties Matter
Using a property provides an interface which is more resistant to change in the future. Let's say some time in the future, a decision is made to add a prefix to the internal code.
Using a public readonly variable exposes your internal structure and you will have a hard time adding the prefix to every line you used the internal variable of the class.
Using a Property, you can just write the following
public string InternalCode {
get { return _prefix + _internalCode; }
}
and you're done!
In my opinion, it's ok to expose public fields (especially if they're readonly or const). Having said that, I'd say that in the example you're presenting, I'd probably go with properties since they'll give you 2 advantages (over fields): 1) better encapsulation and may let you adapt your code in the future and 2) if you're doing data binding, then you do need the properties.
Yes. it is OK to have a public readonly variables (it is just that they can be initialized at the time of definition or constructor).
e.g. Decimal.MaxValue
Having public readonly property is good, if the backing value changes (other than what it was initialized with).
e.g. Environment.TickCount
I thought that Environment.NewLine will be a public readonly variable. Well, it is a public property (get only) and the reason could be to maintain compatibility across different platform.
Short answer: public const is ok, public readonly not necessarily, public get without set not neccessarily.
Objects that cannot be changed without being assigned can be ok. Reference types are dangerous as you can still change their values, even if you cannot change the reference itself.
The problem with the readonly keyword is that it does not mean what you'd understand as logically readonly/immutable. It means more like "can only be assigned in constructor". References cannot be changed, but its values can. There is no "real" readonly keyword provided by c#, unfortunately. See also https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/
Properties cannot have the readonly keyword (https://titombo.wordpress.com/2012/11/11/using-the-c-modifiers/).
As others noted, you can use a property and only define get and no set, though you cannot set that property in the constructor. Using a private set, you can set the property from annywhere in the class, not only in the constructor. The readonly field would be a little more restrictive.

Categories

Resources