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.
Related
I'm not sure of the terminology for this kind of code, but I want to know if it's possible to instantiate variables after the parentheses, but whilst using reflection.
I have a map which gets loaded from an XML file. This is a collection of (int X, int Y, string S) where the X,Y is the position of some terrain, and S is a string representing the type of the terrain. I have a dictionary to pass between the strings and the relevant types; for example one key-value pair might be "Tree", typeof(Tree).
When using reflection, although I know it's possible to instantiate with parameters, the only way I'm comfortable is just by using Activator.CreateInstance(Type t), i.e. with an empty constructor.
When I had the maps hard coded, I would originally instantiate like this (within some i,j for loop):
case: "Tree"
world.Add( new Tree(i,j) );
Whilst starting to think about reflection and my save file, I changed this to:
world.Add( new Tree() { X = i, Y = j }
However, I realised that this won't work with reflection, so I am having to do the following (Tree inherits from Terrain, and the dictionary just converts the XML save data string to a type):
Type type = dictionary[dataItem.typeAsString];
Terrain t = (Terrain)Activator.CreateInstance(type);
t.X = i;
t.Y = j;
world.Add(t);
I would prefer to do this using something like
Type type = dictionary[dataItem.typeAsString];
world.Add((Terrain)Activator.CreateInstance(type) { X = i, Y = j }
Is there any shortcut like this? I guess if not I could edit world.Add to take an X and Y and cast to Terrain in there to access those variables, but I am still curious as to a) what this {var1 = X, var2 = Y} programming is called, and b) whether something similar exists when using reflection.
This syntax is called Object Initializer syntax and is just syntactic sugar for setting the properties.
The code var result = new MyType { X = x } will be compiled to this:
MyType __tmp = new MyType();
__tmp.X = x;
MyType result = __tmp;
You will have to do that yourself using PropertyInfo.SetValue if you know the instantiated type only at runtime or use the normal property setters if the type is known at compile time.
The answer is no, because the object initialization syntax you mention (introduced with LINQ in 3.0) is an illusion of the compiler. As in, when you type this
var foo = new Foo { Bar = "baz" };
the compiler actually converts it into CLS-compliant IL which equates to
var foo = new Foo();
foo.Bar = "baz";
Phil Haack has a great blog post which not only covers the details of this rewriting done by the compiler, but also some side effects it can cause when dealing with types that implement IDisposable
As all of this is nothing but a feint by the compiler, there is no equivalent using reflection (i.e., Activator.CreateInstance(Type t)). Others will give you workarounds, but in the end there really is no direct equivalent.
Probably the closest generic hack you could manage would be to create a method that accepted an object, then used reflection in order to identify the properties of that object and their respective values in order to perform object initialization for you. It might be used something like this
var foo = Supercollider.Initialize<Foo>(new { Bar = "baz" });
and the code would be something like (this is off the top of my head)
public sealed class Supercollider
{
public static T Initialize<T>(object propertySource)
{
// you can provide overloads for types that don't have a default ctor
var result = Activator.CreateInstance(typeof(T));
foreach(var prop in ReflectionHelper.GetProperties(typeof(T)))
ReflectionHelper.SetPropertyValue(
result, // the target
prop, // the PropertyInfo
propertySource); // where we get the value
}
}
You'd have to get each property from the anonymous object, find a property in your target type with the same exact name and type, then get the value from that property in the anonymous object and set the value of your target's property to this value. Its not incredibly hard, but its absolutely prone to runtime exceptions and issues where the compiler chooses a different type for the anonymous type's property, requiring you be more specific (e.g., new { Bar = (string)null }), which screws with the elegance of the thing.
(T)Activator.CreateInstance(typeof(T), param1, param2, ...);
As described HERE.
public sealed class ReflectionUtils
{
public static T ObjectInitializer<T>(Action<T> initialize)
{
var result = Activator.CreateInstance<T>();
initialize(result);
return result;
}
}
public class MyModel
{
public string Name{get;set;}
}
And after that just make the call :
var myModel = ReflectionUtils.ObjectInitializer<MyModel>(m =>
{
m.Name = "Asdf"
});
The advantage is that in this way you will have type safety and use reflection as minimum required, because we all know that reflection is an expensive operation that should be avoided as much as possible.
You could create a constructor which takes those arguments, then use
Activator.CreateInstance(type, i, j)
But you won't be able to use the object initialization syntax. Which is just sugar candy for setting the properties.
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();
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.
While reading and exploring the dynamic keyword I found following line on [MSDN] (in Using Type dynamic (C# Programming Guide)):
The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object.
What is the meaning of static in above line and how does it bypass static type checking?
This is static typing:
string foo = "bar";
foo is now a string, so this will cause a compile time error:
foo = 1;
Even if you use var, it's still statically typed:
var foo = "bar"; // foo is now a string
foo = 1; // still a compile time error
Using the dynamic keyword, means the type won't be static and can be changed, so now you can do this:
dynamic foo = "bar";
foo = 1; // this is now fine.
Now, why it says "the type is a static type" is because in many dynamic languages (like Javascript), you can do something like this:
var foo = { bar: 1 };
Which creates an object with a property called "bar", and then you can do this:
foo.la = 2;
Which adds a new property to the object in foo. But if you try the same trick in C#
dynamic foo = new SomeClassThatDoesntHaveABarProperty();
foo.bar = 2; // runtime error
Nor can you delete a property. You can assign any type to a dynamic variable, but you can't change those types themselves.
If you do need that type of functionality, then you'll want to look at ExpandoObject
As your description says, dynamic functions like an object in a lot of cases. You could do this:
dynamic foo = new Foo();
foo = new Bar();
Just as well like this:
object foo = new Foo();
foo = new Bar();
But the difference comes in when you want to use properties or methods. With dynamic, I can do this:
dynamic foo = new Foo();
foo.FooMethod(); // Note: You WILL get a runtime exception if foo doesn't have a FooMethod
But with an object, I'd need to do this:
object foo = new Foo();
((Foo)foo).FooMethod(); // Note: I HAVE to know the type at compile time here
Which I can only do if I already know I can cast the type in foo to a type of Foo at compile time, and if I knew that already, then I could just have use Foo as my type instead of object.
It means that a variable declared as dynamic will stay of type dynamic and cannot be changed to a variable of type int for example. This concept is bypassed though, because you can change the types of objects that the variable holds.
C# is considered as a strongly typed language because variables are statically typed. That means every variable is typed and the C#-compiler can check if the right types are used in the code. In weakly typed language like most script languages the type of variables is dynamic. They can hold any value.
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