How does Reflection retrieve data assigned to variables? - c#

My understanding so far is that Reflection is used to retrieve the names of Types and their members from an assembly via its metadata. I've come across a few examples of Reflection in action identical to the following example.
class Person
{
public string Name {get;set;}
}
static void Main(string[] args)
{
Person person = new Person();
person.Name = "John";
Console.WriteLine(person.GetType().GetProperty("Name").GetValue(person)); //John
person.Name = "Mary";
Console.WriteLine(person.GetType().GetProperty("Name").GetValue(person)); //Mary
}
I understand how Reflection can get names of Types, members, etc. as this is what's stored in an assembly's metadata, but how does Reflection retrieve the value associated with it? This is dynamic data that changes during a program's execution (as shown in the example), which an assembly's metadata doesn't contain (right?).
Would be grateful for clarification on how Reflection retrieves actual values and whether this is actually the case. Please correct anything I've said that's not correct!

The short answer is that reflection is a feature of the runtime, so it has access to runtime information. Were it a separate library with no runtime "hooks", you're right, it wouldn't be able to get the values of properties at runtime, or make calls, or anything else that wouldn't be essentially observable from the assembly file on disk.
Long answer where I prove this to myself:
Microsoft makes available a reference version of the C# source code used to write the base class libraries for .NET Framework. If we look at the PropertyInfo.GetValue(object) method you use in your example, it's defined here. Following the trail of calls we eventually get to an abstract method of the same name but different parameters. Further down in the source file is the implementing class, RuntimePropertyInfo, and its override of GetValue we see that it is implemented by calling the property's get accessor (as, under the hood, properties are just collections of methods with certain signature conventions - GetGetMethod is a funny name meaning "get me the method defined as get for the current property"):
MethodInfo m = GetGetMethod(true);
if (m == null)
throw new ArgumentException(System.Environment.GetResourceString("Arg_GetMethNotFnd"));
return m.Invoke(obj, invokeAttr, binder, index, null);
If we do a similar spelunking journey on MethodInfo.Invoke, we eventually reach RuntimeMethodHandle.InvokeMethod, which is declared:
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor);
The extern keyword on a class means "I don't have the body for this method in C#, look elsewhere for it". For most users of C# this means they're using DllImport to reference native code, but this method has a different attribute: MethodImpl, with the MethodImplOptions.InternalCall enum value. This is the C# way of saying to the compiler, "I don't have the body, but the actual runtime itself does".
So at the end of our journey we reach the point where the Reflection API relies on the runtime itself. Of course, the runtime and the base class libraries have to be developed in tandem to ensure these sync-up points exist.
Interestingly, the actual standard for .NET - ECMA-335 - makes the Reflection API optional, when the implementation (meaning the runtime + base class libraries) adheres to the bare minimum "Kernel Profile" (cite: 6th Ed., §IV.4.1.3). So actually there are implementations of .NET where you're not explicitly allowed to inspect the runtime like this, but given the reliance some kinds of applications have on reflection, all big implementations (original .NET Framework, .NET Core / the new .NET, and Mono) provide it.

The TLDR is the CLR (Common Language Runtime) keeps track of all your objects in memory and when you call GetValue it retrieves the value for you.
Note this post is a little old, but here is a rough idea of what an object looks like in memory:
Please refer to the part that says Object Instance. An object laid out in memory, contains the following 4 items:
Syncblk
TypeHandle
Instance Fields
String Literals
When you call GetValue, using an OBJECTREF to the object instance, it finds the starting location where your instance fields are stored. From there it can figure out which instance to retrieve based on the type.
I believe the actual call is FieldDesc::GetInstanceField.

Related

Static classes can be used as type arguments via reflection

When trying to use a static class as a type parameter, the C# compiler will throw an error:
var test = new List<Math>();
error CS0718: `System.Math': static classes cannot be used as generic arguments
This has been covered in these questions:
C# - static types cannot be used as type arguments
C# Static types cannot be used as parameters
However, I just realized I can create the type via reflection, and the runtime won't complain:
var test = Activator.CreateInstance(typeof(List<>).MakeGenericType(typeof(Math)));
Am I right in concluding this is supported at the CLR level, but not at the language level?
Or is this a gray area in specifications, meaning I should refrain from using these generic constructed types?
As stated in the comment from BJ Myers, the CLR has no knowledge of "static" classes. The compiler errors are there to prevent you from doing things that can cause serious issues. There are almost always ways around most errors like this (in this case using reflection), but the error when trying to pass the static class as a parameter is a good indication that you should not be doing what you are doing unless you know very well what the repercussions are.
In this case, you should be asking yourself, why are you wanting to pass a static class? Since a static class can have no references to data or other objects, there is no point to pass this. If you need to call functions on a static class without having an explicit reference to it, you can use reflection to invoke its methods. Here is an answer explaining that:
Invoking static methods with reflection

Are there any guidelines for declaring a method which accepts an anonymous object as its argument?

I want to write a method that accepts an anonymous object as its argument. When declaring such a method should the parameter be declared as object or dynamic?
public static void DoSomethingWith(dynamic details) { } OR
public static void DoSomethingWith(object details) { }
My application is a standalone application targetting .NET 4.0.
One reason why I seem to prefer 1 is because when you see the IntelliSense tip that shows the signature of the method, a dynamic argument more clearly states its intent than object.
I will stick with 1 unless there are better reasons to go with 2.
What have been your experiences with this?
If you are targetting framework 4.0 or higher, then its better to use dynamic.
public static void DoSomethingWith(dynamic details)
{
Console.Write(details.X);
Console.Write(details.Y);
}
And call it like:
DoSomethingWith(new { X = "ABC", Y = 10 });
This is hugely dependent on context. There are two existing answers shown that discuss the feature of dynamic that allows access to members, but there is a huge problem there in that it is not obvious to the caller that they are meant to provide those members. In those cases, a type that has those members would, in virtually all cases, be preferred.
In the main, usage of dynamic should be limited to those scenarios where you actually need it (talking to a dynamic type). If you are actually talking to a regular POCO object (maybe an anonymous type, etc), then object might avoid a few complications - but fundamentally object and dynamic are both implemented as object until you start accessing members.
Generally if you are passing a naked object to a method, you will be expecting the method to inspect it, perhaps via reflection. For those purposes, object will be absolutely fine, and provides direct access to .GetType().GetProperties() etc without any indirection.
Basically: without more context on what you are doing inside the method, it is impossible to conclude that either is "better" or "more appropriate", and inside the method dynamic and object are trivially interchangeable (a cast will always succeed, in either direction).
In this case, using dynamic has some advantages over object and no disadvantages that I can see, so your option 1 is clearly the way to go.
Option 1 allows you to use your parameter just as if you had declared it with the real type (which you can't do, since it is anonymous):
public static void DoSomethingWith(dynamic details)
{
var temp = details.Property; // Correct, as long as the object has a property called Property
}
With option 2, this code would have been illegal and you would have to resort to InvokeMethod() and the like, which is more cumbersome to use and to read without providing any real advantages.

What is the __DynamicallyInvokable attribute for?

Looking through System.Linq.Enumerable in DotPeek I notice that some methods are flavoured with a [__DynamicallyInvokable] attribute.
What role does this attribute play? Is it something added by DotPeek or does it play another role, perhaps informing the compiler on how best to optimise the methods?
It is undocumented, but it looks like one of the optimizations in .NET 4.5. It appears to be used to prime the reflection type info cache, making subsequent reflection code on common framework types run faster. There's a comment about it in the Reference Source for System.Reflection.Assembly.cs, RuntimeAssembly.Flags property:
// Each blessed API will be annotated with a "__DynamicallyInvokableAttribute".
// This "__DynamicallyInvokableAttribute" is a type defined in its own assembly.
// So the ctor is always a MethodDef and the type a TypeDef.
// We cache this ctor MethodDef token for faster custom attribute lookup.
// If this attribute type doesn't exist in the assembly, it means the assembly
// doesn't contain any blessed APIs.
Type invocableAttribute = GetType("__DynamicallyInvokableAttribute", false);
if (invocableAttribute != null)
{
Contract.Assert(((MetadataToken)invocableAttribute.MetadataToken).IsTypeDef);
ConstructorInfo ctor = invocableAttribute.GetConstructor(Type.EmptyTypes);
Contract.Assert(ctor != null);
int token = ctor.MetadataToken;
Contract.Assert(((MetadataToken)token).IsMethodDef);
flags |= (ASSEMBLY_FLAGS)token & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_TOKEN_MASK;
}
Without further hints what a "blessed API" might mean. Although it is clear from the context that this will only work on types in the framework itself. There ought to be additional code somewhere that checks the attribute applied to types and methods. No idea where that is located, but given that it would have to need to have a view of all .NET types to have a shot at caching, I can only think of Ngen.exe.
I found that it's used in the Runtime*Info.IsNonW8PFrameworkAPI() suite of internal methods. Having this attribute placed on a member makes IsNonW8PFrameworkAPI() return false for it and thus makes the member available in WinRT applications and shuts up the The API '...' cannot be used on the current platform. exception.
Profiler writers should place this attribute on members emitted by their profiler into framework assemblies, if they want to access them under WinRT.
sorry if I answer late. This attribute is used to call unmanaged code function from managed code. It is used to separate the managed language from the unmanaged language. a barrier of two worlds. It is also used for security reasons. to make unmanaged code reflection inaccessible.

C# class code loaded in RAM?

I would like to know whether the actual code of a C# class gets loaded in RAM when you instantiate the class?
So for example if I have 2 Classes CLASS A , CLASS B, where class A has 10000 lines of code but just 1 field, an int. And class B has 10 lines of code and also 1 field an int as well. If I instantiate Class A will it take more RAM than Class B due to its lines of code ?
A supplementary question, If the lines of code are loaded in memory together with the class, will they be loaded for every instance of the class? or just once for all the instances?
Thanks in advance.
In the desktop framework, I believe methods are JITted on a method-by-method basis. I don't know whether the IL for a class is completely loaded into RAM when the class is first loaded, or whether they're just memory mapped to the assembly file.
Either way, you get a single copy for all instances - at least for non-generic types. For generic types (and methods) it gets slightly more complicated - there's one JIT representation for all reference type type arguments, and one for each value type type argument. So List<string> and List<Stream> share native code, but List<int> and List<Guid> don't. (Extrapolate as appropriate for types with more than one generic type parameter.) You still only get one copy for all instances of the same constructed type though - objects don't come with their own copy of the native code.
An instance of type A will take exactly the same amount of memory as type B. The amount of memory used by an instance of a type is a direct result of the fields which it contains so if both types contain the same fields, then instances of both types will contain the same amount of memory. Of course, if you have variable length fields, such as strings, arrays, collections etc. then you have to take this into account, but if the fields are set to the same values for each type then the same amount of memory will be used.
Within an app domain, the code containing the instructions for the methods of each type will only be loaded once, rather than for each instance of the type. As Jon says, it is important to remember that each closed generic type (with all type parameters stated) is a separate runtime type.
Incidentally, it is not important how many lines of source code your type contains, but how much IL this source code compiles to. However, if one type has 10 line of source code and another has 10,000 then it is highly likely that the IL for that latter class will be much greater. You can examine the IL by using a tool such as .NET Reflector.
This is a good article which describes how and where the IL code is JITted and loaded:
http://msdn.microsoft.com/en-us/magazine/cc163791.aspx

Create object instance without invoking constructor?

In C#, is there a way to instantiate an instance of a class without invoking its constructor?
Assume the class is public and is defined in a 3rd party library and the constructor is internal. The reasons I want to do this are complicated but it would be helpful to know if it's possible using some kind of C# hackery.
NOTE: I specifically do not want to call any constructor so using reflection to access the internal constructor is not an option.
I have not tried this, but there is a method called FormatterServices.GetUninitializedObject that is used during deserialization.
Remarks from MSDN says:
Because the new instance of the object
is initialized to zero and no
constructors are run, the object might
not represent a state that is regarded
as valid by that object.
Actually it sounds like they made the constructor internal just so you can't instantiate it. It may have a builder or factory method.
Check out these articles:
Preventing Third Party Derivation: Part 1
Preventing Third Party Derivation: Part 2
they kind of explain the reasoning.
Contrary to what many believe, a constructor hasn't much to do with the instantiation of an object at all (pretty misleading term). A constructor is a special method that can be called after the instantiation of an object to allow that object to properly initialize itself. In C++ object instantiation allocates memory for the object, in .NET and Java it is both allocated and pre-initialized to default values depending on the type of fields (0, null, false etc.). Then the run-time calls the constructor. The new operator encapsulates these two separate actions into what appears to be a single operation.
Deserialization could never had worked in .NET if it wasn't possible to create an instance without using a constructor. That said, the so called ConstructorInfo type acts as both a new operator and constructor when calling its Invoke(...) method.
See RuntimeHelpers.GetUninitializedObject(Type), available in .NET Core 2.0 / .NET Standard 2.1 and above.
Another answer suggests
FormatterServices.GetUninitializedObject(Type), which directly proxies to RuntimeHelpers.
For completeness, if you want to create an uninitialized object of the same type as another instance, in .NET Core 7 there is also an undocumented AllocateUninitializedClone, with sample code below. I wouldn't recommend this over simply passing instance.GetType() to the documented API.
Likewise, here are notes for if you actually want to hit an internal constructor:
Given a Type and some arguments.
Use Activator.CreateInstance(Type type, object[] args).
Alternatively via Reflection APIs
Use type.GetConstructor. The returned ConstructorInfo has an Invoke method. If you pass an instance, you will effectively reinitialize an object. If you pass no instance, the invocation will instantiate a new object.
Some sample code:
using System.Reflection;
using System.Runtime.CompilerServices;
public static class Program {
public static void Main() {
//
// create uninitialized object instance, then run ctor on it
//
var inst1 = (C)RuntimeHelpers.GetUninitializedObject(typeof(C));
Console.WriteLine(inst1.X); // 0
var ctor = typeof(C).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Array.Empty<Type>());
ctor.Invoke(inst1, null); // Prints "Ran C's Ctor. X is -123"
Console.WriteLine(inst1.X); // 2
//
// create new object with ctor (via reflection)
//
var inst2 = (C)ctor.Invoke(null); // Prints "Ran C's Ctor. X is -123"
Console.WriteLine(inst2.X); // 2
//
// create new object with ctor (via activator)
//
var inst3 = (C)Activator.CreateInstance(typeof(C), BindingFlags.Instance | BindingFlags.NonPublic, null, null, null); // Prints "Ran C's Ctor. X is -123"
Console.WriteLine(inst3.X); // 2
//
// create new uninitialized object of type matching a given instance via undocumented AllocateUninitializedClone
//
var allocateUninitializedClone = typeof(RuntimeHelpers).GetMethod("AllocateUninitializedClone", BindingFlags.Static | BindingFlags.NonPublic, new[] { typeof(object) });
var inst4 = (C)allocateUninitializedClone.Invoke(null, new []{inst2});
Console.WriteLine(inst4.X); // 0
}
public class C {
private C() {
Console.WriteLine($"Ran C's Ctor. X is {X}");
X = 2;
}
public int X { get; } = -123;
}
}
It might be possible to access the constructor via reflection and invoke it like that (but I'm not sure that it will work since the constructor is internal - you'll have to test it).
Otherwise from my knowledge you can't create an object without calling the constructor.
EDIT: You updated your question, you want to construct a class without a constructor. Or call a default "Empty Constructor".
This cannot be done, as the compiler will not generate a default constructor if there is already one specified. However, for the benefit of the readers, here is how to get at a internal, protected, or private constructor:
Assuming your class is called Foo:
using System.Reflection;
// If the constructor takes arguments, otherwise pass these as null
Type[] pTypes = new Type[1];
pTypes[0] = typeof(object);
object[] argList = new object[1];
argList[0] = constructorArgs;
ConstructorInfo c = typeof(Foo).GetConstructor
(BindingFlags.NonPublic |
BindingFlags.Instance,
null,
pTypes,
null);
Foo foo =
(Foo) c.Invoke(BindingFlags.NonPublic,
null,
argList,
Application.CurrentCulture);
Ugly, but works.
Of course, there may be a perfectly legitimate reason to mark a constructor as internal, so you should really consider the logistics of what you want before you abuse that class by getting at it with reflection.
You have to call a constructor to create an object. If there are none available to your liking perhaps you could use a byte code rewriting library like the Mono project's Cecil. It works on Windows as well as Linux. From some of the demos I saw, it looked pretty cool. You can change the protection levels of methods and all sorts of crazy stuff.
If the class (and the classes of objects that it references) is Serializable, you can create a deep copy by serializing using a BinaryFormatter that outputs to a MemoryStream (creating a byte array byte[]), then deserializing. See the answers to this question on converting an object to a byte array. (But note - saving the byte array to use later/elsewhere is likely not to work. IOW don't save the byte array to a file or other persistent form.)
See the System.Activator.CreateInstance function.
What you are asking to do is a violation of the philosophy upon which managed programming was developed. The .Net Framework and C# are built with the principle that, whenever possible, objects should be abstracted away from their underlying memory. Objects are objects, not a structured array of bytes. This is why you can't cast objects to void pointers willy-nilly. When objects are abstracted away from their underlying memory, it is fundamentally invalid to suggest that an object instance can exist without the constructor being invoked.
That said,the .Net framework has made concessions to the fact that in reality, objects are actually represented in memory. With some creativity, it is possible to instantiate value types without invoking their initializers. However, if you feel you need to do it, you're probably doing things wrong.
I noticed the "deadness" of the subject but just for clarification on further readers and to put a final answer that maybe wasn't possible when the question was posted. Here it goes.
It seems that you can instantiate a class without using it's constructors by assigning values to its properties. Here is the address where is the how-to in MSDN for this type of instantiation http://msdn.microsoft.com/en-us/library/bb397680.aspx.
It seems like this is a technique that's not well known because I encountered it in a article in CodeProject and then googled it and didn't find anything about it and later on visited the MSDN Homepage and there was a post that linked me to that exact subject. So it seems that it's an unknown subject rather than a new one because the date on the CodeProject post dates May 2008.
Hope this helps someone else that google's this and comes across with this question.
No one here has quite clarified what is meant by "It can't be done."
The constructor is what creates the object. Your question is akin to "How can I build a sand castle without shaping it like a castle?" You can't -- All you will have is a pile of sand.
The closest thing you could possible do is to allocate a block of memory the same size as your object:
byte[] fakeObject = new byte[sizeof(myStruct)];
(NOTE: even that will only work in MyStruct is a value type)

Categories

Resources