If I have a public property that only has a getter, is it correct to use a private variable to assign the value to then return that value or should I just use return rather then setting the value of userID? In the future we plan to add more functionality that will use the userID field, and Methods will be added to this class that use the userID field. Is there any benefit to one way or the other? Is there some other way that this should be done?
private string userID;
public string ID
{
get
{
if (System.Web.HttpContext.Current.Request.Headers.AllKeys.Contains("UID"))
{
userID = System.Web.HttpContext.Current.Request.Headers["UID"].ToString();
}
else
{
userID = "0000";
}
return userID;
}
}
The way the getter is coded right now does not need an assignment, because subsequent calls ignore the value set by previous methods. However, you could cache the result, like this:
private string userID;
public string ID {
get {
if (userID == null) {
if (System.Web.HttpContext.Current.Request.Headers.AllKeys.Contains("UID")) {
userID = System.Web.HttpContext.Current.Request.Headers["UID"].ToString();
} else {
userID = "0000";
}
}
return userID;
}
}
This implementation avoids reading the "UID" repeatedly by caching the result of the initial retrieval in a private instance variable.
You can do this, but I personally would go, in this case, for a function.
The reason is simple:
One when calls a function, expects that some computation may occur inside of it.
Instead when one calls a property, it's not something that he would expect to happen. When you call a property, you think you call some internal field wrapper.
Repeat, what you do is possible to do, but it's not so good from architectual point of view.
So, my suggession, for this case: use a function.
Use return
You are setting userID in the get
So
public string ID
{
get
{
if (System.Web.HttpContext.Current.Request.Headers.AllKeys.Contains("UID"))
{
return System.Web.HttpContext.Current.Request.Headers["UID"].ToString();
}
else
{
return "0000";
}
}
}
In this instance, you are not persisting any data, therefore having a backing field of userID is pointless.
Because you are using public property, you can change implementation anytime. No userID variable is useless, if you will need it in the future you can always add it.
Related
What is the flow of the below code snippet?
What does return; means?
What will it do when return; executes?
public bool ActionSafeAction
{
get
{
return this.ActionSafeAction;
}
set
{
if (value.Equals(this.ActionSafeAction))
{
return;
}
if (value)
{
this.ActivateItem(this.ActionSafeAction);
this.ActionSASelected = false;
}
this.ActionSafeAction= value;
this.NotifyOfPropertyChange(() => this.ActionSafeAction);
}
}
It will do nothing more of what comes after the return. It immediately returns from the setter and doesn't change any underlying value.
Writing ActionSafeAction = true if ActionSafeAction is already true will hit this return statement and not do anything more.
Properties are little more then Syntax Sugar for Get and Set functions. That is what they are designed to be.
Set in paritcular is effectively a function that takes a parameter "value" and returns void. Except for the name and the way you call it, that set is effectively: public void SetActionSafeAction(bool value). Making getters and setters easily implement and useable - again, that is what Properties are there for.
The return in the if will end the execution of this function, there and then. As it would with any other function that returns void. The rest of the checks and the setting/change notification will not be executed.
I think if we illistruate the getter and setter like below you may understand better. Get and Set are implict definition of two seperated method that effect a particular member.
public class Foo
{
private string myMember;
public string GetMyMember()
{
return myMeber;
}
public void SetMyMember(string value)
{
myMember = value;
}
}
So as you see setter is a actually a void method and when you call return statement at any part of this method it will just leave method without executing rest of the code. This is what happned at your ActionSafeAction propertiy's setter too.
The equal of the above two method will be this property:
public class Foo
{
private string myMember;
public string MyMember
{
get { return myMember; }
set { myMember = value; }
}
}
My primary problem is, that I have a code, which is full of method calls to set/get session variables which makes the source hard to read. I am searching for a better/simpler/more elegant solution. I tried operator overload in classes, wrapper classes, implicit type conversion, but I run into problems with all of them.
I would like to handle session variables like regular variables.
After reading a lot of articles, I came up with the following solution which I'd like to make even simpler:
public class SV_string
{
private string key = ""; //to hold the session variable key
public SV_string(string key)
{
this.key = key; // I set the key through the constructor
}
public string val // I use this to avoid using setter/getter functions
{
get
{
return (string)System.Web.HttpContext.Current.Session[key];
}
set
{
System.Web.HttpContext.Current.Session[key] = value;
}
}
}
I use the same key as the variable name:
public static SV_string UserID = new SV_string("UserID");
UserID.val = "Admin"; //Now the value assignment is quite simple
string user = UserID.val; //Getting the data is quite simple too
UserID = "Admin"; //but it would be even simpler
So is there any way to get the desired behaviour?
Thanks in advance!
You can create the following Session Wrapper and just add your methods/properties/members to it
public static class EasySession
{
public static string UserId
{
get
{
return Get<string>();
}
set
{
Set(value);
}
}
public static string OtherVariableA
{
get
{
return Get<string>();
}
set
{
Set(value);
}
}
public static <datatype> OtherVariableB
{
get
{
return Get<datatype>();
}
set
{
Set(value);
}
}
static void Set<T>(T value, [CallerMemberName] string key = "")
{
System.Web.HttpContext.Current.Session[key] = value;
}
static T Get<T>([CallerMemberName] string key = "")
{
return (T)System.Web.HttpContext.Current.Session[key];
}
}
You will then use it as follow
EasySession.UserId = "Admin"
Better yet. If you are using C# 6.0 then you can add the following to your namespaces
using System;
using static xxx.EasySession;
This will then allow you to just call
UserId = "Admin"
Here is how it works
[CallerMemberName] will get the name of what is calling Get or Set In this case it will then bassically be "UserId
eg Set("UserId","Admin")
Then it will go and just do the following
System.Web.HttpContext.Current.Session["UserId"] = "Admin";
(Ref:https://msdn.microsoft.com/en-us/magazine/dn879355.aspx)
Just use a property to wrap your session variable in.
There's no need for other parts of your code to know that its implementation, uses a Session variable or what key name it is stored in:
public string UserId
{
get
{
return (string)System.Web.HttpContext.Current.Session["UserId"];
}
set
{
System.Web.HttpContext.Current.Session["UserId"] = value;
}
}
I would suggest to create an interface with operations (no properties), and one concrete implementation of that interface that actually accesses those variables as session variables in the HTTP context; but also another mocked implementation that you can use in your unit tests; as HTTP context is not available in those cases.
So in your code you program against those interfaces, and the concrete implementation is injected at run-time. When the site is starting, it's the concrete implementation that uses Session; from tests, it's the mocked implementation.
The reason to use operations instead of properties would be to explicitly tell the user that you are not merely accessing normal properties, but session variables, that might have important side effects.
Warning: avoid to use static!!! This will cause undesirable side effects, like shared data between different users.
I learned c# recently, so when I learned to write properties, I was taught to do it like this:
public string Name { get; set; }
Auto properties are great! But now I'm trying to do something a little more complicated, so I need to write a custom pair of accessors.
private string _Name;
public string Name {
get { return _Name; }
set { _Name = value }
}
I know the compiler makes a private instance variable down in it's murky depths when one uses autos, but I'm spoiled and don't want that private variable sitting around looking pointless.
Is there a way to use custom accessors without a private variable?
Properties don't need backing variables (fields) at all. While they can be used for encapsulating simple fields you can also use them to access other data.
public Decimal GrandTotal { get { return FreightTotal + TaxTotal + LineTotal; } }
or
public string SomeStatus { get { return SomeMethodCall(); } }
If the goal is to simply encapsulate some field with a property you would need some sort of backing field if you are not using automatic properties.
The answer is No, you cannot do that.
It is because of recursion. (See line numbers 9 and 7):
Line 1 : public string Name
Line 2 : {
Line 3 : get
Line 4 : {
Line 5 : return FirstName + " " + LastName;
Line 6 : }
Line 7 : set
Line 8 : {
Line 9 : Name = value; // <-- Goes back to Line 7
Line 10 : }
Line 11 : }
No, I'm afraid not. The compiler is smart enough to make this happen for you on auto-generated properties, but with standard properties I imagine the logic behind something like that would end up getting in the way and doing more harm than good.
For example, what if I create a property like this...
public int SomeValue
{
get
{
return 0;
}
}
Would the compiler (with the feature you're looking for) create a backing private variable? Why? It doesn't need one.
Additionally, if the private value isn't created until compilation time, what are you going to reference in your code:
public string Name {
get { return _Name; }
set { _Name = value }
}
What is _Name? What if you have another value somewhere else called _Name? Then what would the compiler call the backing value for this property? What if I need two backing values? Would the compiler be smart enough for that?
public string Name
{
get
{
return string.Format("{0} {1}", _FirstName, _LastName);
}
set
{
// some parsing magic
}
}
It's been asked before, but I imagine the answer is going to continue to be "no" for the foreseeable future.
An auto-property is syntactic shorthand for simple direct member access. (And I imagine one of its driving forces was simply to try to get people to stop creating public values directly.) Properties can grow in complexity well beyond that very easily and I personally wouldn't want the compiler trying to figure out what I can easily just tell it to do.
I know this is an old question, but there is at least one other option here. I'm doing something similar to the below for my own app.
This might not exactly be for your use case, but it shows that a custom getter and setter can be used without a private instance variable. In this case, the getter and setter are shortcut or helper methods to access the Name property of the User for the Account.
We can let the value be set by doing Account.AccountUser.Name = "John Doe";, but sometimes that seems a bit clunky and it works against the idea of separation of concerns. Do we want someone using the Account class to know there's a User imbedded in it? If for some reason we don't, we now have a way to still update the User.Name even if we make AccountUser private.
In this case, AccountUser is public, but it doesn't have to be. When it's private, a Json or XML conversion utility (such as Newtonsoft) should ignore the AccountUser and show just the Name as if the Account were a flat model, instead of having multiple levels.
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Account
{
public int Id { get; set; }
public User AccountUser { get; set; }
public string Name
{
get
{
return AccountUser.Name;
}
set
{
AccountUser.Name = value;
}
}
}
I've created this "question" as a community-wiki, because there is no right or wrong answer. I only would like to know how the community feels about this specific issue.
When you have a class with instance variables, and you also created properties that are simply getters and setters for these instance variables, should you use the properties inside your own class, or should you always use the instance variable?
Having auto-properties in C# 3.0 made this an even harder decision.
Using properties:
public class MyClass
{
private string _name;
// could be an auto-property of-course
public string Name { get { return _name; } set { _name = value; } }
public void Action()
{
string localVar = Name;
// ...
Name = "someValue";
// ...
}
}
Using instance variables:
public class MyClass
{
private string _name;
public string Name { get { return _name; } set { _name = value; } }
public void Action()
{
string localVar = _name;
// ...
_name = "someValue";
// ...
}
}
(for those who hate member prefixes, I apologize)
Personally, I always use the latter (instance variables), because I feel that properties should only be used by other classes, not yourself. That's why I mostly stay away from auto-properties as well.
Of course, things change when the property setter (or getter) does a little more than just wrapping the instance variable.
Are there compelling reasons to pick one or the other?
I always use instance variables as well. The reason is because properties might be doing stuff like validating arguments (like in a setter) for not null or not empty. If you're using the variable inside your class code, there's no need to go through the extra overhead of those checks (assuming you know the variable value is valid). The properties could be doing other things as well (logging, for example), that are important for the public API, but not for internal usage, so again, it's better to avoid the overhead and just use the instance variable in my opinion.
I think it becomes more difficult to change the internal implementation if the code uses its own public interface.
Difficult to explain but consider these expressions:
mTotalPrice = mPrice * mQuantity;
mTotalPrice = Price * Quantity;
What to do in the second expression if I need to change the internals to express all prices in € instead of $ (without affecting the public interface which still uses $)?
One solution is to make the expression more complex by adding the opposite of the change in the property.
mTotalPrice = Price / Rate * Quantity
The other solution is to start to use the private field instead.
mTotalPrice = mPrice * Quantity
In the end you get a mix of private and public use. The only way to get consistent use is to always use the private field.
I don't like prefixing members either, but actually I find I can write something like this accidently and not spot it until run time. Which kinda tempts me to avoid using properties where they're not necessary... but I still do, currently!
Public String MyString
{
{ get { return this.MyString; } } //<== Stack Overflow
{ set { this.myString = value; } }
}
private String myString;
I think that there is no difference between these two approaches.
Auto-implemented properties is just a quick way to access private members which are created any way.
Example from MSDN:
class Customer
{
// Auto-Impl Properties for trivial get and set
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; }
// Constructor
public Customer(double purchases, string name, int ID)
{
TotalPurchases = purchases;
Name = name;
CustomerID = ID;
}
// Methods
public string GetContactInfo() {return "ContactInfo";}
public string GetTransactionHistory() {return "History";}
// .. Additional methods, events, etc.
}
99% of the time I use the property rather then the instance variable. In the past, I've worked with a lot of code that used the instance variable and when there was a bug associated with that variable, I had to put a breakpoint on every line of code that referenced it.
I decided to use properties instead, either public or private, to wrap around the instance variable. Doing this means that I only have to put a breakpoint in the getter/setter of the property if I need to debug an issue with the instance variable, rather then having (potentially) a lot of breakpoints scattered all over the code.
What is the best way to check for the existence of a session variable in ASP.NET C#?
I like to use String.IsNullOrEmpty() works for strings and wondered if there was a similar method for Session. Currently the only way I know of is:
var session;
if (Session["variable"] != null)
{
session = Session["variable"].ToString();
}
else
{
session = "set this";
Session["variable"] = session;
}
To follow on from what others have said. I tend to have two layers:
The core layer. This is within a DLL that is added to nearly all web app projects. In this I have a SessionVars class which does the grunt work for Session state getters/setters. It contains code like the following:
public class SessionVar
{
static HttpSessionState Session
{
get
{
if (HttpContext.Current == null)
throw new ApplicationException("No Http Context, No Session to Get!");
return HttpContext.Current.Session;
}
}
public static T Get<T>(string key)
{
if (Session[key] == null)
return default(T);
else
return (T)Session[key];
}
public static void Set<T>(string key, T value)
{
Session[key] = value;
}
}
Note the generics for getting any type.
I then also add Getters/Setters for specific types, especially string since I often prefer to work with string.Empty rather than null for variables presented to Users.
e.g:
public static string GetString(string key)
{
string s = Get<string>(key);
return s == null ? string.Empty : s;
}
public static void SetString(string key, string value)
{
Set<string>(key, value);
}
And so on...
I then create wrappers to abstract that away and bring it up to the application model. For example, if we have customer details:
public class CustomerInfo
{
public string Name
{
get
{
return SessionVar.GetString("CustomerInfo_Name");
}
set
{
SessionVar.SetString("CustomerInfo_Name", value);
}
}
}
You get the idea right? :)
NOTE: Just had a thought when adding a comment to the accepted answer. Always ensure objects are serializable when storing them in Session when using a state server. It can be all too easy to try and save an object using the generics when on web farm and it go boom. I deploy on a web farm at work so added checks to my code in the core layer to see if the object is serializable, another benefit of encapsulating the Session Getters and Setters :)
That is pretty much how you do it. However, there is a shorter syntax you can use.
sSession = (string)Session["variable"] ?? "set this";
This is saying if the session variables is null, set sSession to "set this"
It may make things more elegant to wrap it in a property.
string MySessionVar
{
get{
return Session["MySessionVar"] ?? String.Empty;
}
set{
Session["MySessionVar"] = value;
}
}
then you can treat it as a string.
if( String.IsNullOrEmpty( MySessionVar ) )
{
// do something
}
The 'as' notation in c# 3.0 is very clean. Since all session variables are nullable objects, this lets you grab the value and put it into your own typed variable without worry of throwing an exception. Most objects can be handled this way.
string mySessionVar = Session["mySessionVar"] as string;
My concept is that you should pull your Session variables into local variables and then handle them appropriately. Always assume your Session variables could be null and never cast them into a non-nullable type.
If you need a non-nullable typed variable you can then use TryParse to get that.
int mySessionInt;
if (!int.TryParse(mySessionVar, out mySessionInt)){
// handle the case where your session variable did not parse into the expected type
// e.g. mySessionInt = 0;
}
In my opinion, the easiest way to do this that is clear and easy to read is:
String sVar = (string)(Session["SessionVariable"] ?? "Default Value");
It may not be the most efficient method, since it casts the default string value even in the case of the default (casting a string as string), but if you make it a standard coding practice, you find it works for all data types, and is easily readable.
For example (a totally bogus example, but it shows the point):
DateTime sDateVar = (datetime)(Session["DateValue"] ?? "2010-01-01");
Int NextYear = sDateVar.Year + 1;
String Message = "The Procrastinators Club will open it's doors Jan. 1st, " +
(string)(Session["OpeningDate"] ?? NextYear);
I like the Generics option, but it seems like overkill unless you expect to need this all over the place. The extensions method could be modified to specifically extend the Session object so that it has a "safe" get option like Session.StringIfNull("SessionVar") and Session["SessionVar"] = "myval"; It breaks the simplicity of accessing the variable via Session["SessionVar"], but it is clean code, and still allows validating if null or if string if you need it.
This method also does not assume that the object in the Session variable is a string
if((Session["MySessionVariable"] ?? "").ToString() != "")
//More code for the Code God
So basically replaces the null variable with an empty string before converting it to a string since ToString is part of the Object class
Checking for nothing/Null is the way to do it.
Dealing with object types is not the way to go. Declare a strict type and try to cast the object to the correct type. (And use cast hint or Convert)
private const string SESSION_VAR = "myString";
string sSession;
if (Session[SESSION_VAR] != null)
{
sSession = (string)Session[SESSION_VAR];
}
else
{
sSession = "set this";
Session[SESSION_VAR] = sSession;
}
Sorry for any syntax violations, I am a daily VB'er
Typically I create SessionProxy with strongly typed properties for items in the session. The code that accesses these properties checks for nullity and does the casting to the proper type. The nice thing about this is that all of my session related items are kept in one place. I don't have to worry about using different keys in different parts of the code (and wondering why it doesn't work). And with dependency injection and mocking I can fully test it with unit tests. If follows DRY principles and also lets me define reasonable defaults.
public class SessionProxy
{
private HttpSessionState session; // use dependency injection for testability
public SessionProxy( HttpSessionState session )
{
this.session = session; //might need to throw an exception here if session is null
}
public DateTime LastUpdate
{
get { return this.session["LastUpdate"] != null
? (DateTime)this.session["LastUpdate"]
: DateTime.MinValue; }
set { this.session["LastUpdate"] = value; }
}
public string UserLastName
{
get { return (string)this.session["UserLastName"]; }
set { this.session["UserLastName"] = value; }
}
}
I also like to wrap session variables in properties. The setters here are trivial, but I like to write the get methods so they have only one exit point. To do that I usually check for null and set it to a default value before returning the value of the session variable.
Something like this:
string Name
{
get
{
if(Session["Name"] == Null)
Session["Name"] = "Default value";
return (string)Session["Name"];
}
set { Session["Name"] = value; }
}
}
in this way it can be checked whether such a key is available
if (Session.Dictionary.ContainsKey("Sessionkey")) --> return Bool
If you know it's a string, you can use the String.IsEmptyOrNull() function.
Are you using .NET 3.5? Create an IsNull extension method:
public static bool IsNull(this object input)
{
input == null ? return true : return false;
}
public void Main()
{
object x = new object();
if(x.IsNull)
{
//do your thing
}
}