I have an initial snippet which deserealized parameters, checks for value and handles the error:
var param = js.Deserialize<int?>(jqData.Params);
if (param.HasValue)
{
resp.ReturnValue = param.Value;
}
else
{
//handle error code
}
Now, during my modification, I have changed the method to accept a list of class parameters instead of nullable integers
var param = js.Deserialize<ClassName>(jqData.Params);
Now it invalidates .HasValue and .Value methods.
My question is: How do I properly modify these two lines so it would hold the same meaning as initial if statement?
Thus far I only thought about switching to if (param != null), but I cannot think of proper equivalent to .Value.
As soon as ClassName is a class (see - a reference type) you just need to check if it is not null.
If it is not - then the variable holds a reference to an object that you use as-is.
I have this really weird problem and I'm sure I'm missing something obvious here. I have these two lines:
HttpContext.Current.Session[listModelType + "ListModel"] = listModel;
listModel.ProductRows = new Collection<ProductRow>(listModel.ProductRows.Where(r => r.ParentRowId == 0).ToList());
After the second line is executed my session object is updated as well (according to "Watch" in Visual Studio)
What am I missing here?
I have tried
int i = 0;
HttpContext.Current.Session["i"] = i;
i++;
and HttpContext.Current.Session["i"] remains 0.
See value types and reference types.
The int is a value type so will be stored "as-is" on the moment of assignment; your listModel is a reference type so you store a reference to the object in your session, not the value of the object.
You'll have to create a new instance of listModel if you want the one in your session untouched.
In your first example you are storing a reference to the object (The lists memory location). So if the list is updated it will reflect in the session. This is a reference type.
In the second example you are using a value type:
int i = 0;
HttpContext.Current.Session["i"] = i;
i++;
You declare i and set it to 0 (Value type)
You store the value 0 in the session. (Not the memory location of i)
You increment i but the session still has the value 0
In the first example your session variable is pointing to a reference so it gets updated because the two references are pointing to the same value.
The second session variable is pointing to a primitive (value) type so they have separate copies of value.
In the first example your session variable is pointing to a reference so it gets updated because the two references are pointing to the same value.
so before assigning to the session you convert it into Json and then assign
HttpContext.Current.Session[listModelType + "ListModel"] = JsonConvert.SerializeObject(listModel);
Note: JsonConvert is from name space Newtonsoft.Json namespace in c#
In second line if value changes in listModel object that does't reflect session.
but when you want to retreive the value from session you should convert to object form Json
if (HttpContext.Current.Session[listModelType + "ListModel"] != null)
{
listModel = JsonConvert.DeserializeObject<*CLASS name of lsitmodel*>((string)HttpContext.Current.Session[listModelType + "ListModel"]);
}
The correct way should be:
int i = 0;
i++;
HttpContext.Current.Session["i"] = i;
the HttpContext.Current.Session["i"] remains 1.
In the first example your session variable is pointing to a reference so it gets updated because the two references are pointing to the same value.
so before assigning to the session you convert it into Json and then assign
HttpContext.Current.Session[listModelType + "ListModel"] = JsonConvert.SerializeObject(listModel);
Note: JsonConvert is from name space Newtonsoft.Json namespace in c#
In second line if value changes in listModel object that does't reflect session. but when you want to retreive the value from session you should convert to object form Json
if (HttpContext.Current.Session[listModelType + "ListModel"] != null) {
listModel = JsonConvert.DeserializeObject<*CLASS name of lsitmodel*>((string)HttpContext.Current.Session[listModelType + "ListModel"]);
}
I want the value of session into string without type casting and conversion in ASP.NET.
But I want without any conversion get the value of Session["username"] into temp variable.
Example - the correct way is:
string temp;
Session["username"] = "Joy";
temp = Session["username"].ToString();
Since Session is of type Object (so you can put in anything) you need to cast it back to String if you want to read it.
The preffered way of doing so is (since it may not exist in your session yet)
string temp = Session["username"] as String;
if (temp == null)
{
//Doesn't exist in Session yet, so create and add
}
A session holds objects as values and therefore you need to cast the object into the correct type to gain the type's strength.
The session value can be null, so you need to check that.
string temp;
Session["username"]="Joy";
temp=Session["username"] as string;
if you use this:
object temp = Session["username"]; // temp is just a basic object.
Another issue is, since the session holds objects, value types are "boxed" into objects.You can't use the "as" cast when you want to case value types, so:
int intTemp;
Session["num"]= 7; // int is boxed into an object
intTemp = (int)Session["num"]; // unboxed back to int
intTemp = Session["num"] as int; // cannot be done!!!
Please try this..
temp=Session["username"] as string;
As session is an object it is necessary to type cat it to the prefered type..
I am retrieving data from database table.
By giving input as 1 in
textbox1(voucherno)-->damagedetail =
web.getdamageddetail(Convert.ToInt32(voucherno.Text));
I want get branchno as output in textbox2(branchno)
branchno.Text = damagedetail.branchno.ToString();
but am getting error
Object reference is not set into instance of an object.
Check my second line.
Is second line coding correct?
damagedetail.branchno is null.
Try this:
if (damagedetail.branchno != null)
branchno.Text = damagedetail.branchno;
else
branchno.Text = "abcd";
Either your object property is not filled thus when you retrive the value "branchno" from the object the value is equal to null, or your not filling the property in your "getdamageddetail" method
I'm trying to validate my understanding of how C#/.NET/CLR treats value types and reference types. I've read so many contradicting explanations I stil
This is what I understand today, please correct me if my assumptions are wrong.
Value types such as int etc live on the stack, Reference types live on the managed heap however if a reference type has for example has an instance variable of type double, it will live along with its object on the heap
The second part is what I am most confused about.
Lets consider a simple class called Person.
Person has a property called Name.
Lets say I create an instance of Person in another class, we'll call it UselessUtilityClass.
Consider the following code:
class UselessUtilityClass
{
void AppendWithUnderScore(Person p)
{
p.Name = p.Name + "_";
}
}
and then somewhere we do:
Person p = new Person();
p.Name = "Priest";
UselessUtilityClass u = new UselessUtilityClass();
u.AppendWithUnderScore(p);
Person is a reference type, when passed to UselessUtilityClass -- this is where I go - nuts...the VARIABLE p which is an instance of the Person reference is passed by VALUE, which means when I write p.Name I will see "Priest_"
And then if I wrote
Person p2 = p;
And I do
p2.Name = "Not a Priest";
And write p's name like below I will get "Not a Priest"
Console.WriteLine(p.Name) // will print "Not a Priest"
This is because they are reference types and point to the same address in memory.
Is my understanding correct?
I think there is some misunderstanding going on when people say All objects in .NET are passed by Reference, this doesn't jive based on what I think. I could be wrong, thats why I have come to the Stackers.
Value types such as int etc live on the stack. Reference types live on the managed heap however if a reference type has for example has an instance variable of type double, it will live along with its object on the heap
No, this is not correct. A correct statement is "Local variables and formal parameters of value type which are neither directly in an iterator block nor closed-over outer variables of a lambda or anonymous method are allocated on the system stack of the executing thread in the Microsoft implementation of the CLI and the Microsoft implementation of C#."
There is no requirement that any version of C# or any version of the CLI use the system stack for anything. Of course we do so because it is a convenient data structure for local variables and formal parameters of value type which are not directly in an iterator block or closed-over outer variables of a lambda or anonymous method.
See my articles on this subject for a discussion of (1) why this is is an implementation detail, and (2) what benefits we get from this implementation choice, and (3) what restrictions the desire to make this implementation choice drives into the language design.
http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx
http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx
Person is a reference type, when passed to UselessUtilityClass -- this is where I go - nuts...
Take a deep breath.
A variable is a storage location. Each storage location has an associated type.
A storage location whose associated type is a reference type may contain a reference to an object of that type, or may contain a null reference.
A storage location whose associated type is a value type always contains an object of that type.
The value of a variable is the contents of the storage location.
the VARIABLE p which is an instance of the Person reference is passed by VALUE,
The variable p is a storage location. It contains a reference to an instance of Person. Therefore, the value of the variable is a reference to a Person. That value -- a reference to an instance -- is passed to the callee. Now the other variable, which you have confusingly also called "p", contains the same value -- the value is a reference to a particular object.
Now, it is also possible to pass a reference to a variable, which many people find confusing. A better way to think about it is when you say
void Foo(ref int x) { x = 10; }
...
int p = 3456;
Foo(ref p);
what this means is "x is an alias for variable p". That is, x and p are two names for the same variable. So whatever the value of p is, that's also the value of x, because they are two names for the same storage location.
Make sense now?
Value types such as int etc live on
the stack, Reference types live on the
managed heap however if a reference
type has for example has an instance
variable of type double, it will live
along with its object on the heap
Correct.
You can also describe it as the instance variables being a part of the memory area allocated for the instance on the heap.
the VARIABLE p which is an instance of
the Person reference is passed by
VALUE
The variable is actually not an instance of the class. The variable is a reference to the instance of the class. The reference is passed by value, which means that you pass a copy of the reference. This copy still points to the same instance as the original reference.
I think there is some misunderstanding
going on when people say All objects
in .NET are passed by Reference
Yes, that is definitely a misunderstanding. All parameters are passed by value (unless you use the ref or out keywords to pass them by reference). Passing a reference is not the same thing as passing by reference.
A reference is a value type, which means that everything that you ever pass as parameters are value types. You never pass an object instance itself, always it's reference.
When you pass a person, it is making a copy of the reference - do not confuse this with a copy of the object. In other words, it is creating a second reference, to the same object, and then passing that.
When you pass by ref (with the ref/out keyword), it is passing the same reference to the object that you are using in the caller, rather than creating a copy of the reference.
Maybe this some examples can show you differences between reference types and value types and between passing by reference and passing by value:
//Reference type
class Foo {
public int I { get; set; }
}
//Value type
struct Boo {
//I know, that mutable structures are evil, but it only an example
public int I { get; set; }
}
class Program
{
//Passing reference type by value
//We can change reference object (Foo::I can changed),
//but not reference itself (f must be the same reference
//to the same object)
static void ClassByValue1(Foo f) {
//
f.I++;
}
//Passing reference type by value
//Here I try to change reference itself,
//but it doesn't work!
static void ClassByValue2(Foo f) {
//But we can't change the reference itself
f = new Foo { I = f.I + 1 };
}
//Passing reference typ by reference
//Here we can change Foo object
//and reference itself (f may reference to another object)
static void ClassByReference(ref Foo f) {
f = new Foo { I = -1 };
}
//Passing value type by value
//We can't change Boo object
static void StructByValue(Boo b) {
b.I++;
}
//Passing value tye by reference
//We can change Boo object
static void StructByReference(ref Boo b) {
b.I++;
}
static void Main(string[] args)
{
Foo f = new Foo { I = 1 };
//Reference object passed by value.
//We can change reference object itself, but we can't change reference
ClassByValue1(f);
Debug.Assert(f.I == 2);
ClassByValue2(f);
//"f" still referenced to the same object!
Debug.Assert(f.I == 2);
ClassByReference(ref f);
//Now "f" referenced to newly created object.
//Passing by references allow change referenced itself,
//not only referenced object
Debug.Assert(f.I == -1);
Boo b = new Boo { I = 1 };
StructByValue(b);
//Value type passes by value "b" can't changed!
Debug.Assert(b.I == 1);
StructByReference(ref b);
//Value type passed by referenced.
//We can change value type object!
Debug.Assert(b.I == 2);
Console.ReadKey();
}
}
The term "pass by value" is a little misleading.
There are two things you are doing:
1) passing a reference type (Person p) as a parameter to a method
2) setting a refence type variable (Person p2) to an already existing variable (Person p)
Let's look at each case.
Case 1
You created Person p pointing to a location in memory, let's call this location x. When you go into method AppendWithUnderScore, you run the following code:
p.Name = p.Name + "_";
The method call creates a new local variable p, that points to the same location in memory: x. So, if you modify p inside your method, you will change the state of p.
However, inside this method, if you set p = null, then you will not null out the p outside the method. This behavior is called "pass by value"
Case 2
This case is similar to the above case, but slightly different. When you create a new variable p2 = p, you are simply saying that p2 references the object at the location of p. So now if you modify p2, you are modifying p since they reference the same object. If you now say p2 = null, then p will now also be null. Note the difference between this behavior and the behavior inside the method call. That behavioral difference outlines how "pass by value" works when calling methods
The specifications says nothing about where to allocate value types and objects. It would be a correct C# implementation to say allocate everything on the heap and there Atr situations where values are allocated on the heap other than those you write.
int i = 4;
Func dele = ()=> (object)i;
Will result in (a copy of) i being allocated on the heap because the compiler will make it into a member of a class eventhough it's not declared as such. Other than that you're pretty much spot on. And no everything is not passed as reference. It would be closer to the thruth to state that every parameter was passed by value but still not entirely correct (e.g. ref or out).