I am very confused with properties in asp.net.
I just don't understand why we use properties and when I should use them. Could anybody elaborate a little on this.
public class Customer
{
private int m_id = -1;
public int ID
{
set
{
m_id = value;
}
}
private string m_name = string.Empty;
public string Name
{
set
{
m_name = value;
}
}
public void DisplayCustomerData()
{
Console.WriteLine("ID: {0}, Name: {1}", m_id, m_name);
}
}
Properties provide the opportunity to protect a field in a class by reading and writing to it through the property. In other languages, this is often accomplished by programs implementing specialized getter and setter methods. C# properties enable this type of protection while also letting you access the property just like it was a field.
Another benefit of properties over fields is that you can change their internal implementation over time. With a public field, the underlying data type must always be the same because calling code depends on the field being the same. However, with a property, you can change the implementation. For example, if a customer has an ID that is originally stored as an int, you might have a requirements change that made you perform a validation to ensure that calling code could never set the ID to a negative value. If it was a field, you would never be able to do this, but a property allows you to make such a change without breaking code. Now, lets see how to use properties.
Taken From CSharp-Station
There are a couple of good reasons for it. The first is that you might need to add validation logic in your setter, or actually calculate the value in the getter.
Another reason is something to do with the IL code generated. If you are working on a large project that is spread over multiple assemblies then you can change the code behind your property without the application that uses your assembly having to recompile. This is because the "access point" of the property stays the same while allowing the implementation code behind it to be altered. I first read about this when I was looking into the point of automatic properties as I didnt see the point between those and a normal public variable.
It's easy.
All fields in class MUST be private (or protected). To show fields to another class yyou can use properties or get/set methods. Properties a shorter.
P.S. Don't declare write-only properties. It is worst practices.
Properties are a convenient way to encapsulate your classes' data.
Quoting from MSDN:
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.
Let's consider two common scenarios:
1) You want to expose the Name property without making it changeable from outside the class:
private string m_name = string.Empty;
public string Name
{
get
{
return m_name;
}
}
2) You want to perform some checks, or run some code every time the data is accessed or set:
private string m_name = string.Empty;
public string Name
{
get
{
return m_name;
}
set
{
m_name = (String.IsNullOrEmpty(value)) ? "DefaultName" : value;
}
}
see:
http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx
The most important reason is for validation purpose in setter and manipulation part can be implemented in get part.
For Ex.
Storing weekdays, which should be from 1-7, if we take normal variable and declare it as public, anyone can assign any value.
But in Properties setter you can control and validate.
The next one you can use it for tracking. That means, you can know how many times set and get functions has been called by clients (statistical purpose, may be not useful frequently).
Finally, you can control read only, write only and read/write for the properties according to your requirements.
Related
I'm using Entity Framework (DB First) on a new project and wanted to add some customisation to the classes generated. However, my changes are obviously lost every time that the edmx is refreshed. I was just wondering if there is a design pattern for handling this sort of thing?
As an example, suppose I have a class with a integer property; StatusID - and I'd like to extend the entity class so that the status value can also be accessed/set via the related enum and finally a property that gets a text representation of that Enum from the description attribute. This all works, but those customisations are lost when the model is refreshed. I appreciate that the property can be converted to an enum, so the latter property that gets the description of the enum is perhaps a better example for this question.
I think I know the answer but I just wanted to put this out there in case there were some magic tricks that would allow this to work and prevent those customisations from being lost.
public int StatusID { get; set; }
public Enumerations.ValidationStatus StatusEnum
{
get
{
return (Enumerations.ValidationStatus)StatusID;
}
set
{
StatusID = (int)value;
}
}
public string StatusText
{
get
{
return MyMethodThatGetsTheEnumDescription(StatusEnum);
}
}
Two Solutions to work around the problem:
User Data Transfer Object(DTO) nd put the enum there. then use Automapper or manually map between the DB Model and the DTO Model (best practice)
Instead of enum you can use extension functions on the model and define your getter, setters and any extra properties you want as extension functions to the class
(will add some complexity to your models)
is it possible to make this validation:
class Man {
#Unique
String name;
}
class Order {
#Valid
List<Man> manCollection;
}
where is unique logic is: every item in collection manCollection is unique.
You could make this snippet ambiguous just by adding a Customer class that contains a List of Orders:
class Man {
#Unique
String name;
}
class Order {
#Valid
List<Man> manCollection;
}
class Customer {
#Valid
List<Order> orderCollection;
}
Then one couldn't possibly know whether the Man objects must be unique within a given Order or within a given Customer (or both).
So I don't think it's possible with this exact syntax, regardless of what the Bean Validation APIs allow.
What you could do is move the annotation to manCollection, e.g. #UniqueMen List<Man> manCollection;, and implement a ConstraintValidator<List<Man>>.
If it's useful to you, you could even make a more generic #UniqueContent annotation, but that would be much more complex. You would need to pass the target type as a parameter (#UniqueContent(target = Man.class)) and write a validator that parses annotations on the target class in its initialize method. Be careful to use some caching mechanism, though, because annotation parsing is quite slow.
I am having a little play with Flex and I'm curious as to a few things.
Firstly for my instance variables I can define something like
private var _count:int = 0;
It then seems that If I have a getter and setter for count e.g
public function get count():int
{
return _count;
}
public function set count(value:int):void
{
_count = count;
}
I can from within another function call something like
count++;
which in turn sets _count to increase by one.
I.E I can seemingly access count through count or _count because I have a getter and setter..
That is correct understanding?
For something like the above is good OOP practice to have the getter and setter or simply call _count++;
Thanks
I will point out that your set count method changes the variable _points. If that is a typo, then:
Yes; that is a correct understanding. It sounds like your tests already proved that.
The private var _count will not be accessible by other classes with a reference to an instance of your class; but the public 'count' will be.
Getter and Setters are useful for performing other functionality within the class. In the context of a Flex UI Component, you may dispatch an event, or invalidate the component through one of the Flex component invalidation methods.
Separating out the get and set methods also allow you to create properties that are read only, or properties that are write only, just by leaving out the respective get or set method.
IF that is not a typo; then I have no idea why count++ would change the _count variable at all; and something else is going on with the count that you haven't shown us.
in web application, i am trying to declare property, i found in some of blogs that they declare property like this :
public System.Nullable<DateTime> LoginDateTime { get; set; }
what is the meaning of the above property.
This is called an auto-implemented property.
In C# 3.0 and later, auto-implemented properties make
property-declaration more concise when no additional logic is required
in the property accessors. They also enable client code to create
objects. When you declare a property as shown in the following
example, the compiler creates a private, anonymous backing field that
can only be accessed through the property's get and set accessors.
The compiler will transform this code into something like:
private System.Nullable<DateTime> xxx;
public System.Nullable<DateTime> LoginDateTime
{
get
{
return xxx;
}
set
{
xxx = value;
}
}
The "generated" code is then called a property:
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.
About System.Nullable<>
Value type cannot have a null value (compared to reference types). The use of System.Nullable<> allows representing the correct range of values for its underlying value type, plus an additional null value.
Another notation to System.Nullable<DateTime> is DateTime?
Nullable Types (C# Programming Guide)
It's declaring a LoginDateTime property that can either contain a value or be null; it's equivalent to this:
public DateTime? LoginDateTime { get; set; }
Read more here: http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
What part of it are you confused about?
It happens to be a C# property of type Nullable(T), which is a structure that allows you to make other structures nullable. As in you can set the property to null, Note, you can't set a normal DateTime variable to null.
The property is written with some syntactic sugar called Auto-Implemented properties.
Having the name LoginDateTime it probably stores the Date and Time of when the person logged on.
Pardon me if this question has already been asked. HttpContext.Current.Session["key"] returns an object and we would have to cast it to that particular Type before we could use it. I was looking at various implementations of typed sessions
http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx
http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx
http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx
and I felt that we needed to add some more code (correct me if I was wrong) to the SessionManager if we wanted to add a new Type of object into session, either as a method or as a separate wrapper. I thought we could use generics
public static class SessionManager<T> where T:class
{
public void SetSession(string key,object objToStore)
{
HttpContext.Current.Session[key] = objToStore;
}
public T GetSession(string key)
{
return HttpContext.Current.Session[key] as T;
}
}
Is there any inherent advantage in
using
SessionManager<ClassType>.GetSession("sessionString")
than using
HttpContext.Current.Session["sessionString"] as ClassType
I was also thinking it would be nice
to have something like
SessionManager["sessionString"] = objToStoreInSession,
but found that a static class cannot have an indexer. Is there any other way to achieve this ?
My thought was create a SessionObject which would store the Type and the object, then add this object to Session (using a SessionManager), with the key. When retrieving, cast all objects to SessionObject ,get the type (say t) and the Object (say obj) and cast obj as t and return it.
public class SessionObject { public Type type {get;set;} public Object obj{get;set;} }
this would not work as well (as the return signature would be the same, but the return types will be different).
Is there any other elegant way of saving/retrieving objects in session in a more type safe way
For a very clean, maintainable, and slick way of dealing with Session, look at this post. You'll be surprised how simple it can be.
A downside of the technique is that consuming code needs to be aware of what keys to use for storage and retrieval. This can be error prone, as the key needs to be exactly correct, or else you risk storing in the wrong place, or getting a null value back.
I actually use the strong-typed variation, since I know what I need to have in the session, and can thus set up the wrapping class to suit. I've rather have the extra code in the session class, and not have to worry about the key strings anywhere else.
You can simply use a singleton pattern for your session object. That way you can model your entire session from a single composite structure object. This post refers to what I'm talking about and discusses the Session object as a weakly typed object: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html
Actually, if you were looking to type objects, place the type at the method level like:
public T GetValue<T>(string sessionKey)
{
}
Class level is more if you have the same object in session, but session can expand to multiple types. I don't know that I would worry about controlling the session; I would just let it do what it's done for a while, and simply provide a means to extract and save information in a more strongly-typed fashion (at least to the consumer).
Yes, indexes wouldn't work; you could create it as an instance instead, and make it static by:
public class SessionManager
{
private static SessionManager _instance = null;
public static SessionManager Create()
{
if (_instance != null)
return _instance;
//Should use a lock when creating the instance
//create object for _instance
return _instance;
}
public object this[string key] { get { .. } }
}
And so this is the static factory implementation, but it also maintains a single point of contact via a static reference to the session manager class internally. Each method in sessionmanager could wrap the existing ASP.NET session, or use your own internal storage.
I posted a solution on the StackOverflow question is it a good idea to create an enum for the key names of session values?
I think it is really slick and contains very little code to make it happen. It needs .NET 4.5 to be the slickest, but is still possible with older versions.
It allows:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
to work exactly like:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;