My textbook is referring to the this reference and it first implies that a property is somewhat static and does not store one with each object, but one for the entire class. Then later it says that a property is nonstatic. I am really confused. What is it?
Properties can be static or not static.
Static properties have the 'static' keyword, default is not static.
Properties that are static are stored for the entire class (there is only one).
Properties that are not static are stored per instance.
A property can be both static and non-static you decide which by using the static keyword.
public static int StaticProperty {get; set; }
public int InstanceProperty {get; set; }
On a side note, a property is actually two methods (or just one if you only implement the set or get).
public int MyProperty {get; set; }
is equivalent to
public void set_MyProperty(int value);
public int get_MyProperty();
Related
For proper encapsulation, should I use a private property with a manual getter method like in Java:
public class Foo {
private int Prop { get; set; }
public Foo
{
Prop = 1;
}
public int GetProp()
{
return Prop;
}
}
Or should I simply use a public property?
public class Foo {
public int Prop { get; private set; }
public Foo
{
Prop = 1;
}
}
Properties are the way of creating getters and setters in C#, so there is no reason to create a getter method, like you would in Java.
In other words: You should use the second example.
Typically the proper way to do this is:
private int prop;
public int Prop
{
get { return prop; }
set { prop = value; } //do other stuff within set if needed.
}
This way you have access to everything, but can still do something custom (commonly NotifyPropertyChanged) if needed.
A property is just a syntactic sugar for get_PropertyName and set_PropertyName methods in c#.
public class Foo
{
public int Prop { get; private set; }
}
Is equivalent to:
public class Foo
{
private int _prop;
private void set_prop(int value) { _prop = value; }
public int get_prop() { return _prop; }
}
It's best that you use auto properties when possible and use properties with backing fields when you need to add logic to the getter/setter of individual fields.
If the property is going to be private, as it is in your first example, you should just use a field.
The point of a Property is usually that you have a get and set function, that can be used mostly like a variable. Your first example is really wierd - why not just make the getter only public? Readonly and Writeonly properties are not a uncommon sight:
//Public property with private get or writeonly
public int Prop { private get; set; }
//Readonyl property
public int Prop { get; private set; }
One important rule regarding the Backing field: It is very important that you do not mix up the Property and it's backing field, especially in class code. If you use Autoimplement Properties, that danger is non-existant. If your code is more complex than that, a common approach is to append a underscore (_) to the backing field name. Prop/prop is too easy to mix up. _Prop and Prop are really hard to mix up ,especialyl for autocompletion features.
In general, methods represent actions and properties represent data. While both your examples can be used identically, the 'proper' way of representing state is through properties, and using properties correctly tells consumers of your object that this is representing state, not an action.
You should also consider how things like serialization and intellisense are expecting properties instead of methods.
I have this code:
public string foo { get; set; }
Now, I interpret this as my object has a public property called foo, and both it's accessor's are public. If I write this:
private string foo { get; set; }
I interpret that as my object has a private property called foo, and both it's accessor's are private. I understand making the property itself private. What I don't understand is why the accessor's must be more restrictive? If I write:
private string foo { public get; public set; }
I interpret that my object has a private property called foo, and both's it's accessor's are public, which is the behavior that I want. I'd like the private property with public accessors. I mean, if I have to write a Get/Set method, I will. But I'm just confused as to why this is.
A property is actually (under water) nothing more than two methods:
public string foo { get; set; }
will translate into:
public string get_foo() { ... }
public void set_foo(string value) { ... }
These methods can only have ONE access modifier, not a combination of two.
If I remember correcly, C#v1 did not support access modifiers for the getters and setters. There was one access modifers for the property which was used for both functions.
In v2 it was possible to "override" one of getter/setter-pair, this way overrwriting the "other" function. There was no use to override both getters/setters, because in that would render the property-access modifier useless.
Why the access modifier for the getter/setter is more restrictive has, in my opinion, something to do with easier implementing interfaces which always have (implicitly public) properties.
For more info, read: http://msdn.microsoft.com/en-us/library/75e8y5dd(v=vs.80).aspx
Why you need such a property
private string foo { public get; public set; }
If you want to have you get set public, then make the property public.
The compiler will first check the access of the property and then its method. If the property is public then its method can have either public or private or any accessor
I am using NHibernate for my C# pojects and therefore I have several model classes.
Lets assume the following example:
using System;
namespace TestProject.Model
{
public class Room
{
public virtual int Id { get; set; }
public virtual string UniqueID { get; set; }
public virtual int RoomID { get; set; }
public virtual float Area { get; set; }
}
}
Mapping these objects with NHibernate works fine so far. Now I want to generate a new Room object and I want to store it in the database. To avoid setting each member seperatly, I add a new constructor to the model class.
Below the virtual members I write:
public RoomProperty()
{
}
public RoomProperty(int pRoomId, int pArea)
{
UniqueID = Guid.NewGuid().ToString();
RoomID = pRoomId;
Area = pArea;
}
Analyzing my code with FxCop tells me the following:
"ConstructorShouldNotCallVirtualMethodsRule"
This rule warns the developer if any virtual methods are called in the constructor of a non-sealed type. The problem is that if a derived class overrides the method then that method will be called before the derived constructor has had a chance to run. This makes the code quite fragile.
This page also describes why this is wrong and I also understand it. But I am not shure how to solve the problem.
When I erase all constructors and add the following method...
public void SetRoomPropertyData(int pRoomId, int pArea)
{
UniqueID = Guid.NewGuid().ToString();
RoomID = pRoomId;
Area = pArea;
}
.... to set the data after I called the standard constructor I cant start my aplication becaue NHibernate fails initializing. It says:
NHibernate.InvalidProxyTypeException: The following types may not be used as proxies:
VITRIcadHelper.Model.RoomProperty: method SetRoomPropertyData should be 'public/protected virtual' or 'protected internal virtual'
But setting this method to virtual would be the same mistake as when I just set the virtual members in the constructor.
How can I avoid these mistakes (violations)?
The problem lies in virtual set. Passing a value to the virtual property in the base class constructor will use overriden set instead base set. If overriden set relies on data in derived class, then you are in trouble, because constructor of derived class was not done yet.
If you are absolutely sure, that any subclass will not use any data of its state in overriden set, then you can initialize virtual properties in base class constructor. Consider adding an appropriate warning to the documentation.
If possible, try to create backing fields for each property and use them in base class contructor.
You can also postpone properties initialization to the derived class. To achieve that, create an initializing method in the base class that you invoke in constructor of derived class.
I expect one of the following to work:
Make the properties non-virtual (preferred as long as NHibernate supports it).
Change from auto-implemented properties to properties with an explicit backing field, and set the fields in the constructor instead of setting the properties.
Create a static Create method which constructs the object first, and then sets values to the properties before returning the constructed object.
Edit: From the comment I see option #3 was not clear.
public class Room
{
public virtual int Id { get; set; }
public virtual string UniqueID { get; set; }
public virtual int RoomID { get; set; }
public virtual float Area { get; set; }
public static Room Create(int roomId, int area)
{
Room room = new Room();
room.UniqueID = Guid.NewGuid().ToString();
room.RoomID = roomId;
room.Area = area;
return room;
}
}
IMHO, good idea is to make base class - abstract and its constructor - protected.
Next, inherited classes have their constructor private and - for outer world - uniform static method like "Instance", which first of all, initializes the constructor, then - calls whole set of class methods in correct sequence and finally - returns the instance of the class.
i'm learning C#.
ok, i have a problem:
i have a class :
class Couple{
private double first{private set; public get;}
private double second{private set; public get;}
}
first question: am i right, that these properities have public getter and private setter? (it's sounds strange, i know, but need to know difference between private/public field and private/public property with public/private set/get )
and second question.
if i want a class :
class AnyCouple{
public Type AnyCouple {public set; public get;}
private AnyCouple first{private set; public get;}
private AnyCouple second{private set; public get;}
}
how to make it?
dummy questions, i know, sorry
The class you want is Tuple.
As for the general principle, you want Generics.
Regarding properties, you can apply a different access modifier to one of the accessors, but not to both (the one to which you don't apply a modifier uses the modifier applied to the property itself). And the applied modifier must be more restrictive, not more relaxed:
private double first {private set; public get;} // wrong, 2 modifiers
private double first { set; public get;} // wrong, a relaxed modifier
public double first {get; private set;} // correct
A nice article on MSDN about that.
For your first question, yes, you are right. The properties first and second have a private setter and a public getter. However, as written, your code won't compile. If you specify an access modifier on a getter or setter it must be more restrictive than the access modifier for the property and you can't specify an access modifier on both properties. Additionally, note that in idiomatics C#, we write the getter first and setter second and we give properties PascalCase names like
public double First { get; private set; }
This will achieve a property named First with a public getter and a private setter and it is written idiomatically.
For your second question, you should use generics. You could do it all like this:
public class MyTuple<T1, T2> {
private readonly T1 first;
public T1 First { get { return this.first; } }
private readonly T2 second;
public T2 Second { get { return this.second; } }
public MyTuple(T1 first, T2 second) {
this.first = first;
this.second = second;
}
}
But, this is already built in to the .NET Framework. You can just use Tuple<T1, T2>. Note that its Item1 and Item2 properties (analogous to your first and second) have a public getter; it is backed by a private readonly field.
As for the first question, the private double first means that both the getter and setter will be private. Really you want public double first and then control the accessibility of the getter and setter as you have done. I believe that when the compiler sees this kind of property declaration, it creates code for the backing store (always a private field) and get/setters as you specifiy.
As mentioned by #GSerg, the Tuple class is what you want.
In VB.NET it is possible to do the following in a class.
Public Property MyProperty As String
At this point a getter and setter is automagically created for you and you can refer to variable defined by the property as such.
Me._MyProperty = "BlahBlah"
Is there an equivalent mechanism in C# ?
public string MyProperty {get; set;}
by default they are both public accessors, you can make one of them private like this:
public string MyProperty {get; private set;}
In C# you cannot refer to the underlying variable of auto implemented properties directly.