Is it possible to do this
void Instantiate(Class c) {
c = new Class();
}
Class c1 = null;
Instantiate(c1);
c1.property .....gives me null reference exception
Can a class be instantiated inside a method and be used outside it?
Yes, but you have to pass the argument by reference:
void Instantiate(ref Class c) {
c = new Class();
}
Class c1 = null;
Instantiate(ref c1);
All parameters are passed by value by default. In case of reference types the reference is the value being passed. Because of that if you change internal state of the object it will be visible outside of the method (e.g. adding an element to a list). But, but you can't replace the entire instance - that change won't be visible to the caller.
Let's say you have a List<T>:
var myList = new List<T>();
let's assume it's initialized in some memory location 0x1234. Now you pass it to a method which takes List<T>:
void doSomethingWithAList(List<T> list)
{
}
And later
doSomethingWithAList(myList);
At this point both myList outside of the method and list inside doSomethingWithAList point at the same addres (0x1234). If you do list.Add(default(T)) and later callmyList.Lenghth you'll get back 1, because they are both pointing at the same object at 0x1234.
However, if inside doSomethingWithAList you assign a new list to list:
void doSomethingWithAList(List<T> list)
{
list = new List<T>();
}
only list points at that new object. myList still points at 0x1234.
Once you make the method take List<T> by reference updating what list points too will also update what myList points to outside of the method.
I think the confusion is that all parameters are passed by value to another method. So when you pass in a reference type into a method, a copy of the reference gets passed into the method.
In your example, c1 points to null initially. When you call instantiate, a copy of c1, I'll name it c1_ is created (which points to null) and c1_ gets passed into the method Instantiate, not c1.
There are two ways to get your code to work. The first way is the use of the ref keyword. The ref keyword will allow c1 to be passed into the method.
void Instantiate(ref Class c) {
c = new Class();
}
And call it as such
Instantiate(ref c1);
I would recommend that you use a return type in this specific example.
Class Instantiate() {
return new Class();
}
You can use the method the following way.
Class c1 = Instantiate();
Related
Please see the code below:
var MyViewModel = new MyViewModel();
var MyDomainModel = AutoMapper.Map<MyDomainModel>(MyViewModel);
MyDomainModel = service.DoSomething(MyDomainModel);
The MyDomainModel reference is overwritten with the return type from: service.DoSomething();
Should I be passing MyDomainModel by reference in this case or does it not really make much difference?
I am looking at a lot of code that was written like the above and I am wandering if there is a reason for it that I am not aware of.
If, as the comments indicate, DoSomething just modifies properties of the object passed in but returns the same object then you could replace
MyDomainModel = service.DoSomething(MyDomainModel);
with
service.DoSomething(MyDomainModel);
It doesn't matter because either way MyDomainModel will still refer to the same object.
We have two possible cases here.
The Original Instance is Modified
public MyDomainModel DoSomething(MyDomainModel model)
{
model.Property1 = X;
model.Property2 = Y;
return model;
}
Then you have to pass the original instance as argument but you can transform your function into a void since classes are passed by reference:
public void DoSomething(MyDomainModel model)
{
model.Property1 = X;
model.Property2 = Y;
}
var MyViewModel = new MyViewModel();
var MyDomainModel = AutoMapper.Map<MyDomainModel>(MyViewModel);
service.DoSomething(MyDomainModel);
// MyDomainModel.Property1 is set to X now...
The Original Instance is Replaced
public MyDomainModel DoSomething(MyDomainModel model)
{
// ...
return (new MyDomainModel());
}
In this case, if the method doesn't make any use of model, you can basically avoid passing it as argument:
public MyDomainModel DoSomething()
{
// ...
return (new MyDomainModel());
}
var MyViewModel = new MyViewModel();
var MyDomainModel = AutoMapper.Map<MyDomainModel>(MyViewModel);
MyDomainModel = service.DoSomething();
Otherwise, if the method creates the new instance keeping some retaining some properties of the old one, you have to keep it:
public MyDomainModel DoSomething(MyDomainModel model)
{
MyDomainModel newModel = new MyDomainModel();
newModel.Property1 = model.Property1;
return newModel;
}
var MyViewModel = new MyViewModel();
var MyDomainModel = AutoMapper.Map<MyDomainModel>(MyViewModel);
MyDomainModel = service.DoSomething(MyDomainModel);
if the DoSomething method is changing the input parameter to point to a new object then you must use ref otherwise I don't see the point of passing by ref.
edit
if as you've mentioned within the comments that you're only changing the state of the input parameter then there is no need at all to return the reference to the object that was passed in because the changes will remain intact after the method call.
in fact, whether the input parameter is being passed by ref or not there shouldn't be a reason to return the same reference of the object passed in. so, therefore, you can make the method service.DoSomething(MyDomainModel); return void.
It depends what the method does. Objects are always passed by reference in this manner of use (though simply saying "passed by reference" doesn't really go far enough to explain what happens under the hood), so if DoSomething manipulates MyDomainMidel the changes will survive when the method returns. If, however, DoSomething makes a new domain model instance and returns it, and you want to preserve it, you have to keep the returned value
Here are some examples:
//the passed in person is renamed, you don't need to capture the return value
public Person Rename(Person p){
p.Name = "John";
return p;
}
//the passed in person is not renamed, you need to capture the return value
public Person Rename(Person p){
p = new Person();
p.Name = "John";
return p;
}
//the passed in person is swapped out for a new one, you don't need to capture the return value
public Person Rename(ref Person p){
p = new Person();
p.Name = "John";
return p;
}
The last example differs from the middle one thanks to the ref keyword. You can conceive that in the case if the middle call, you have a person in the calling method, you call Rename (myPerson) and the framework creates a copy of the reference to the person object, and passes the copy reference to the called method. If the called method manipulates properties of the instance then the original instance is modified even though it's accessed via a copy reference. If the copy reference is pointed to a whole new object, then any change to properties affect the new object, not the original. The copy reference goes out of scope when the method returns and the edits are lost as e copy pointer silently disappears, hence why you need to capture the return value if you want it
In the case of the ref keyword, rather than a copy of the reference to your myPerson being passed, the original reference to the instance is passed. If the method points it to a new object instance, then when control returns to the calling method, it will find its myPerson instance has been replaced with an entirely new object. The use cases for this are narrow, and it's not a favoured way to program because it essentially gives the called method the power to manipulate things beyond its scope of responsibility; the calling method might not appreciate having its variable contents trashed and replaced by a method call. There is nearly always a way to avoid using ref and while you're unclear on the mechanics of it, it is best to avoid using it, even if it does mean you have to code like the middle example.
You code like the middle example a lot, perhaps without realising; strings are immutable, so every call to e.g, .Substring creates a new string representing the shorter sequence of characters, so you have to keep the return value. As a result, some developers fall into the habit even for methods that only manipulate properties of an existing object and never use the new keyword
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am doing this,
public Order Add(Order order)
{
order.thisA = GetValue1();
// update the state of object
return order;
}
Would i be any beneficial if I use Ref or Out here instead ?
Further implementation would require me to add this method,
public Order[] UpdateCollection(Order[] orderCollection)
{
foreach(Order o in orderCollection)
o = Update(o);
return orderCollection;
}
Please tell me in light of best practices as well.
Context:
At the moment I am only returning INT id of the order but in future maybe I need to return more properties, but here is the full context,
https://codereview.stackexchange.com/questions/97778/crud-operation-class#
In this case:
public MyObject Update(MyObject object)
{
object.thisA = GetValue1();
// update state of object
return object;
}
You are not changing MyObjects reference so:
You don't need to return the object back.
You don't need to use ref.
You don't need to use out.
Using out is for initializing an object (You must assign a value in the function).
MyObject obj; // didn't assign anything
Method(out obj);
public void Method(out MyObject obj){
obj = new MyObject(); // assigned
}
using ref is in case you might change the reference of the object inside the method:
MyObject obj = new MyObject();
Update(ref obj);
public void Update(ref MyObject obj)
{
obj = new MyObject(); // changing the ref!!!
obj.thisA = GetValue1();
}
BTW, in your case you don't need to do anything:
public void UpdateCollection(Order[] orderCollection)
{
foreach(Order o in orderCollection)
Update(o);
}
public void Update(MyObject object)
{
object.thisA = GetValue1();
}
You are foreaching an array and updating the object and not the reference.
You use ref if there is a chance that you want to change the reference instead of the object's data.
Example:
public void RetargetReference(ref List<string> originalList)
{
originalList = new List<string>();
originalList.Add("World");
}
List<string> inList = new List<string>();
inList.Add("Hello");
RetargetReference(ref inList);
This will change the reference of inList. It will now point to a new list which contains one entry "World". The list that contained "Hello" will no longer be available to you unless you have another reference to it.
ref parameters can be useful if you want to change parameter you passed in during the execution of the method.
out will be used to have the method create a new object instance without you being able to pass a value in!
Example:
public void CreateReference(out List<string> newList)
{
newList = new List<string>();
newList.Add("Hello World");
}
List<string> list;
CreateReference(out list);
After that, list will point to a new List<string> instance. Inside the method you have no access to whatever newList actually "points to". You will always have to create a new instance.
out parameters can be useful if you want your method to return more than one result. For example, the following method would return a bool to indicate success and two out parameters that contain the data:
public bool TrySplitString(string source, out string part1, out string part2)
{
part1 = String.Empty;
part2 = String.Empty;
string[] parts = source.Split('=');
if (parts.Length != 2)
return false;
part1 = parts[0];
part2 = parts[1];
return true;
}
Objects are generally passed by reference in C#, so the following method actually changes the data "outside" the method:
public void ChangeList(List<string> list)
{
list.Add("World");
}
List<string> inList = new List<string>();
inList.Add("Hello");
ChangeList(inList);
After that, inList contains two entries: "Hello" and "World".
The reason why sometimes you return the object that was passed in as a parameter is that this allows so called "method chaining" where you can "write sentences" instead of "commands". You'll see that in my next example:
public static List<string> CreateList()
{
return new List<string>();
}
public static List<string> AddItem(this List<string> list, string item)
{
list.Add(item);
return list;
}
public static List<string> DoSomethingWithList(this List<string> list)
{
...;
return list;
}
You can use this code and write something like this:
List<string> list = CreateList().AddItem("Hello").DoSomethingWithList();
Return object back may be used for create "method chaining", like this:
someObject.Update(MyObject object).MyObjectMethod1().MyObjectMethod2();
I can't really workout what you really trying to achieve. However, i will give you some basics.
In C#, arguments can be passed to parameters either by value or by reference.
If your MyObject is a reference type (eg: class) then it is passed to function as reference and hence you will end up in modifying same object. In other way, any change you make on this instance (within the function) will have a direct impact on that instance and it will continue to be true in the current execution environment.
On the other hand, if MyObject is a value type (eg: struct) then a copy of it will be passed to method. That is, original instance of your value type is not altered even if you modify the members within the method. This is default behavior when it comes to value type.
Now assume a scenario where you wanted to modify the original instance of value type. This can be achieved only if you pass the reference of your value type. Here comes ref and out. Using these keyword, you can pass parameter by reference. There are differences between ref and out, which can be learned separately. However, keeping your context in mind, the ref and out both allow the called method to modify a parameter.
ref means that the parameter has a value on it before going into the function. So that the function can read and or change the value within it. On the other hand, out means that the parameter has no official value before going into the function. The called function must initialize it before parameter goes out from function.
Looking at this Microsoft article How to: Write a Copy Constructor (C#) and also this Generic C# Copy Constructor, wouldn't it be best/safe to use a reference to the class instance than to use a plain copy of the instance ?
public class Myclass()
{
private int[] row;
public MyClass(ref MyClass #class)
{
for(int i = 0; i<#class.row.Length;i++)
{
this.row[i] = #class.row[i];
}
}
}
What ref actually means:
void Change(SomeClass instance)
{
instance = new SomeClass();
}
void ChangeRef(ref SomeClass instance)
{
instance = new SomeClass();
}
Later...
SomeClass instance = new SomeClass();
Change(instance);
//value of instance remains unchanged here
ChangeRef(ref instance);
//at this line, instance has been changed to a new instance because
//ref keyword imports the `instance` variable from the call-site's scope
I can't see how this functionality would be useful with respect to a copy constructor.
Object by nature is reference not a value type. I do not see any good reason what extra advantage you would get doing it. But yes you might get into problems because of it, consider this -
You created an object and passed it with reference to couple of classes and those classes are now having access to the address of reference itself. Now I have got all the powers to go and change the reference itself with another object's reference. If here, another class had this object it is actually working on some stale object and other classes can not see what changes are being made and you are in chaos.
I do not see any use of doing it, rather it is dangerous. It does not sounds like a OO way of writing code to me.
The ref keyword is used when a method should be allowed to change the location of a reference. Reference types always pass their reference into a method (but the location of the reference cannot be modified via assignment). Values types pass their value.
See: Passing Parameters
Example:
void PassingByReference(List<int> collection)
{
// Compile error since method cannot change reference location
// collection = new List<int>();
collection.Add(1);
}
void ChangingAReference(ref List<int> collection)
{
// Allow to change location of collection with ref keyword
collection = new List<int>();
collection.Add(2);
}
var collection = new List<int>{ 5 };
// Pass the reference of collection to PassByReference
PassingByReference(collection);
// collection new contains 1
collection.Contains(5); // true
collection.Contains(1); // true
// Copy the reference of collection to another variable
var tempCollection = collection;
// Change the location of collection via ref keyword
ChangingAReference(ref collection);
// it is not the same collection anymore
collection.Contains(5); // false
collection.Contains(1); // false
// compare the references use the default == operator
var sameCollection = collection == tempCollection; // false
Having a user defined class, like this:
class Foo
{
public int dummy;
public Foo(int dummy)
{
this.dummy = dummy;
}
}
And having then something like this:
ArrayList dummyfoo = new ArrayList();
Foo a = new Foo(1);
dummyfoo.add(a);
foreach (Foo x in dummyfoo)
x.dummy++;
How much is a.dummy?
How can i create my ArrayList so that a.dummy equals 2, meaning that my ArrayList contains basically pointers to my objects and not copies.
It is already 2, as Array/Collections (to be precise any .NET Class/reference type) are passed by reference by default.
In fact the reference variable is passed by value, but behaves as if passed by reference.
Why ->
Consider var arr = new ArrayList();
The above statement first creates an ArrayList object and a reference is assigned to arr. (This is similar for any Class as class are reference type).
Now at the time of calling,
example -> DummyMethod(arr) ,
the reference is passed by value, that is even if the parameter is assigned to a different object within the method, the original variable remains unchanged.
But as the variable points(refer) to same object, any operation done on underlying pointed object is reflected outside the called method.
In your example, any modification done in for each will be reflected in the arrayList.
If you want to avoid this behavior you have to create copy/clone of the object.
Example:
Instead of
foreach (Foo x in dummyfoo)
x.dummy++;
Use
foreach (Foo x in (ArrayList)dummyfoo.Clone())
x.dummy++;
It already contains references, not copies. When doing this:
Foo a = new Foo(1);
dummyfoo.Add(a);
a reference to a is passed, not a copy.
Hence, dummy will be 1 initially and then 2 after the increments.
Anyway, you're better off using generics:
List<Foo> dummyfoo = new List<Foo>();
Foo a = new Foo(1);
dummyfoo.Add(a);
foreach (Foo x in dummyfoo)
x.dummy++;
You declared Foo as a class. Classes are reference types. It already works like this. Give it a try:
class Program
{
static void Main(string[] args)
{
ArrayList dummyfoo = new ArrayList();
Foo a = new Foo(1);
dummyfoo.Add(a);
foreach (Foo x in dummyfoo)
x.dummy++;
Console.WriteLine(a.dummy); //Prints 2!
}
}
class Foo
{
public int dummy;
public Foo(int dummy)
{
this.dummy = dummy;
}
}
As an aside, a generic List<T> is preferred over the deprecated ArrayList type.
It is already 2: Here is your code on ideone that verifies that..
Unlike value types (i.e. structs), reference (i.e. class) objects are passed by reference.
P.S. Generics are available since C#2.0, so consider using List<Foo> in place of ArrayList for improved type safety.
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).