Return reference not copy with GetValue() - c#

using reflection in c# I need to get only reference to object, not copy, is it possible?
object data = actualData.GetType().GetProperty(properties[0]).GetValue(actualData, null);
variable data should be only reference - if I change something inside, I would like to perform the same changes in actualData variable, but it seems to copy value from actual data and any change stay only in data variable. Any suggestion?
Thanks!

It seems that your property is of value type. Or maybe it is of reference type but it creates a new instance of resulting class instead of reusing it.
If this is a case, then I'm afraid this can't be done in general - properties are methods, so the result value of property is calculated, you cannot observe when that result would be changed.
But if you can change class of which actualData is the instance, then you can implement INotifyPropertyChanged interface and subscribe to its event PropertyChanged in your code.
If this is not possible then you can remember the result of ...GetProperty(), but you have to call GetValue() on it each time when you need the data.

Related

Passing an object as a constructor parameter seems to be passing by reference instead of value

I'm having strange issue where I am creating a new object which contains a parameter for another object (paramObj) I use through my function. So, paramObj is used in an object constructor, but it ends up being altered after the constructor is called. Since C# is pass by value, I'm not sure why this is happening.
My code:
void MyFunction(List<string> filesets)
{
foreach(Fileset fs in filesets)
{
//At this point, fs.allFiles.Count is 30. The MyNewObject class
//takes a Fileset as a parameters and eventually clears the
//Fileset.allFiles List, making the count 0.
MyNewObject tmpObj = new MyNewObject(fs, null, "default");
//At this point, fs.allFiles.Count is 0, but I expect it to be 30
}
}
The MyNewObject class simply clears the allFiles list contained within a Fileset class. Why is that showing up after the constructor if C# is pass by value?
You´re right in that everything in .NET is passed by value. Even references - and this is what fs actually is - are passed by value. Thus, when you pass fs around your method will have a copy of that reference. This reference however references the exact same object, making any change on that reference modifiying the backing object also.
So in your constructor you have a second reference to the FileSet-instance referenced by fs.
This more or less leads to the conclusion, that objects are effectivly passed by reference.
There´s no simple way to circumvent this. It depends on why you even modify anything on that object within the constructor at all. You could try to copy the provided object referenced by fs within your constructor, e.g. by implementing IClonable within FileSet or by providing a copy-constructor within that class or whatever. However depending on what FileSet and it´s members are you will need some deep copy of the provided instance.
For further reading on how to make a deep copy of an object look here: Deep cloning objects
Normally, all the objects are passed by reference as parameter to the method. On the other hand most of the primitive data types such as integer, double, Boolean etc. are passed by value.

How the Object Modification works?

I have two objects say Object1,Object2.
The two objects have the same properties.
My code is like below
Object1.property1=Object2.property1; // Object2.property1=**x**
Object2.property1= **y**;
When I try to retrieve the Object1.property1 it is displaying y.
Here I Don't want to change the Object1.property1 but it is Getting Modified when Object2.property1 has changed.
My Questions is
Why my code is behaving like that or Is there any concept that i don't know in c# ?
It is behaving like that because you don't actually have 2 objects. You only have one.
Object1 and Object2 are simply variables. They are not objects themselves. They store a "reference" that points to the object. You can use the variables to access the object. In some point in your code, you most probably have written
Object1 = Object2;
or
Object2 = Object1;
This makes the two variables hold 2 references that refers to the same object. When you edit the object by accessing through the variable Object1, you can see the effect by accessing the object through Object2. Because they are the same object.
Fore more details you read concept of : Deep Copy vs Shollow Copy
if you want to change that behavior than you need to make use of cloning/copy , right now you are assigning reference and that's why its changing in both the object ,
as property is byte array then you can do like this ,Array.CopyTo Method (Array, Int32)
Array1.CopyTo(Array2, 0);//
so in your case its like
Object2.property1.CopyTo(Object1.property1,0);
Object2.property1= **y**;
You might have to have a look at this Microsoft doc. The concept of value and reference types variables is a very basic and very important concept of c#.
Simply said: if you crate an object like this:
object2 = object1;
You dont really create a new object. You just reference the first object with the second one. If eiter of those gets edited both do at the same time since they are the same object after all.
Unfortunately there is no built in way to simply clone an object, but you coud create an overload to create a new object and pass the source object as argument tocopy all the attributes individually. if there are too many attributes you could also use reflection to procedurally copy all attributes defined in the object.

Please explain the late binding process

I'm trying to make a simple addin. The developers documentation states this:
Late bind to ETABS.exe, create an instance of the ETABSObject, and get a reference to the cOAPI interface.
I'm very confused on how to late bind to an already running exe. If you could give me an example or point me in the right direction I would really appreciate it. I've been banging my head on wall for days.
Early Binding
When performing Early Binding, an object is assigned to a variable declared to be of a specific object type. Early binding objects are basically a strong type objects or static type objects. While Early Binding, methods, functions and properties which are detected and checked during compile time, perform other optimizations before an application executes. The biggest advantage of using early binding is for performance and ease of development.
Example :
System.IO.FileStream FS ;
FS = new System.IO.FileStream("C:\\temp.txt", System.IO.FileMode.Open);
Above code creates a variable FS to hold a new object and then assigns a new object to the variable. Here type is known before the variable is exercised during run-time.The FileStream is a specific object type, the instance assigned to FS is early bound.
While preforming Early Binding the compiler can ensure at compile time that the function will exist and be callable at runtime. Moreover the compiler guarantees that the function takes the exact number of arguments and that they are of the right type and can checks that the return value is of the correct type.
Late binding
By contrast, in Late binding functions, methods, variables and properties are detected and checked only at the run-time. It implies that the compiler does not know what kind of object or actual type of an object or which methods or properties an object contains until run time. The biggest advantages of Late binding is that the Objects of this type can hold references to any object, but lack many of the advantages of early-bound objects.
Example:
//The var keyword instructs the compiler to infer the type of the variable
// from the expression on the right side of the initialization statement.
var eTabsObj = null;//notice the var keyword
//instead of var you can use an interface variable to hold reference
// of late bind object
eTabsObj = CreateObject("<create an instance of ETABSObject>");//executed at runtime
Above code does not require a reference to be set beforehand, the instance creation and type determination will happen at runtime. It is important to note that the Late binding can only be used to access type members that are declared as Public. Accessing members declared as Friend or Protected Friend result in a run-time error.
To answer your specific question, you are creating an object during runtime, and it makes sense because when the author of the ETABS.exe wrote the code he didn't knew how you would like to use it in your project.You created an object in the way which suits your requirement.
Notice how we used var to hold reference to ETABS object , var is basically a syntactic sugar which infers object type from the object being assigned. Now instead of using var you could use an interface variable which ETABS class implements to hold the reference of the object.
While perform late binding there is a possibility of the target function may not exist. Also the target function may not accept the arguments passed to it, and may have a return value of the wrong type.
Hope this helps !

C# return type of function

What does GetNode return, a copy or a reference to the real value?
public GraphNode GetNode(int idx)
{
return Nodes[idx];
}
In other words will this code change the real value or it will change a copy returned from GetNode?
GetNode(someIndex).ExtraInfo = something;
Thanks
Depending on wherever GraphNode is a class or struct. In case of a class you'll be changing "real" value. Struct is the opposite.
It depends on your definition of GraphNode.
If it is a class (by reference) it will return the same instance;
or if it is a struct (value-type) then you'll get a new instance.
In other words will this code change the real value or it will change
a copy returned from GetNode?
GetNode(someIndex).ExtraInfo = something;
If GetNode() returns a struct / value type you will actually get a compilation error in C#:
Cannot modify the return value of 'GetNode(someIndex)' because it is
not a variable
This is exactly because the compiler is trying to protect you from changing a copied value that goes nowhere. Your example makes only sense if GetNode() returns a reference type.
The only way to get the example to compile for a value type is by separating retrieval of the return value from the property assignment:
var node = GetNode(someIndex);
node.ExtraInfo = something;
In this case as other posters have mentioned it does depend on whether GetNode() returns a reference type or a value type. For a reference type you are changing the original class instance that GetNode() returns a reference to, for a value type you are modifying a new, copied instance.
The way classes work in C# is that they can be passed around as pointers.
You can set the values inside it, like you have in your example, and it will change the original.
Setting the actual class itself cannot be done without a wrapper though.
It will return a reference (in case GraphNode is a class) to a GraphNode object, so the original object will be altered.

Question about c# optimizer

If I write:
SomeType simpleName = classWithLongName.otherLongName;
And then use "simpleName" instead of "classWithLongName.otherLongName", will this change the program in any way (for instance performance wise)?
What does the compiler do with this? Does it copy+paste "classWithLongName.otherLongName", everywhere I use "simpleName".
No, the C# compiler doesn't translate a call to "simpleName" to be the same as copying and pasting "classWithLongName.otherLongName". The difference could be profound or simply semantic, but what you're doing is assigning the value from classWithLongName.otherLongName to simpleName. Whether the type is a value type or a reference type will determine exactly what happens and what will happen if you manipulate that value, but you're not creating a function pointer or delegate in doing that.
Whether it will have an effect on performance really isn't something that can be answered here, other than to say that it won't have a NEGATIVE effect. We can't say if it will have a positive effect, since that would depend on what actually happens when you call classWithLongName.otherLongName. If that's an expensive operation, then this could make it faster, but the downside would be that any differences in value upon subsequent calls to classWithLongName.otherLongName wouldn't be reflected if you cached its value in simpleName.
It depends what "otherLongName" is actually doing. If it's a property, then the difference is between executing the property several times or only executing it once. That may or may not change the behaviour of the program in a significant way, depending on what it's doing.
The compiler is only allowed to cache the value and re-use it itself when you always type "classWithLongName.otherLongName" if it knows that the value will not change in the course. However, this is seldom the case.
Therefore, if "classWithLongName.otherLongName" does perform some computation, you'll usually get better performance by caching it manually in a local variable as you suggested. However, keep in mind that you are working with a cached value and that changes in the original value or property will not be reflected on your cached value.
The length of the name however is just metadata and has no influence whatsoever on runtime performance, since the name is already resolved to an internal handle during compilation.
Is this a question about instances or classes?
For instance
namespace MyCompany.MyApp.LongNamespaceName
{
public class MyClassWithALongName {
public SomeType AnInstanceProperty {get;set;}
public static SomeType AStaticProperty {get { ... }}
}
}
Now:
//this gets the static property
SomeType simpleName = MyClassWithALongName.AStaticProperty;
Alternatively:
MyClassWithALongName anInstanceWithALongName = new MyClassWithALongName();
//this gets the instance property
SomeType simpleName = anInstanceWithALongName.AnInstanceProperty;
These will behave in different ways.
There's another case here though, you can create an alias for the actual name of the class:
using simpleName = MyCompany.MyApp.LongNamespaceName.MyClassWithALongName;
...
simpleName anInstance = new simpleName ();
If classWithLongName.otherLongName is a property, than changes to simpleName will NOT change classWithLongName.otherLongName.
If classWithLongName.otherLongName is a public data member (a field) of a value type, than changes to simpleName will NOT change classWithLongName.otherLongName.
If classWithLongName.otherLongName is a public data member (a field) of a reference type, than changes to simpleName WILL change classWithLongName.otherLongName.
Assuming your type is an object (reference) type then simpleName will end up containing a reference to the object returned by classWithLongName.otherLongName. If you are then going to make lots of calls to properties on that object then you may get a performance improvement, especially if otherLongName is a property as opposed to a field.
You can always make it a function.
SomeType simpleName() { return classWithLongName.otherLongName; }

Categories

Resources