Issues in create the instance of singilton class using reflection in C#
Scenario -
I have a public class (named class1) with only internal constructors. Assume this class exists in assembly class1.dll. Now I want to create the instance of class1 inside another public class (named class2) that exist in another assembly (class2.exe).
Case A
Class1.dll
namespace ns1
{
public class class1 {
internal class1(int i)
{
Console.WriteLine("init ns1.Class1, args value: " + i);
}
public void print()
{
Console.WriteLine("executing ns1.class1.print()");
}
}
}
Class2.exe
namespace ns2
{
class Class2
{
static void Main(string[] args)
{
Assembly assembly = Assembly.LoadFrom(@"c:\Class1.dll");
Type type = assembly.GetType("ns1.class1", true, true);
ConstructorInfo[] constructors = type.GetConstructors(
BindingFlags.NonPublic | BindingFlags.Instance);
object o = constructors[0].Invoke(
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new object[] { 1 },
System.Globalization.CultureInfo.InvariantCulture);
// typecasting does not work
ns1.class1 instance = o as ns1.class1;
}
}
}
The type cast of object o to ns1.class1 fails. Program things that ns1.class1 defined in assembly loaded form c:\class1.dll is different that the one declared in the statement but they are exactly the same. Can anyone explain the reason? Is it because I am not using Binder?
Case B
Class1.dll
namespace ns1
{
public class class1:Stack {
internal class1(int i)
{
Console.WriteLine("init ns1.Class1, args value: " + i);
}
public void print()
{
Console.WriteLine("executing ns1.class1.print()");
}
}
}
Class2.exe
namespace ns2
{
class Class2
{
static void Main(string[] args)
{
Assembly assembly = Assembly.LoadFrom(@"c:\Class1.dll");
Type type = assembly.GetType("ns1.class1", true, true);
ConstructorInfo[] constructors = type.GetConstructors(
BindingFlags.NonPublic | BindingFlags.Instance);
object o = constructors[0].Invoke(
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new object[] { 1 },
System.Globalization.CultureInfo.InvariantCulture);
// typecasting works
Stack instance = o as Stack;
MethodInfo[] methods = type.GetMethods();
methods[0].Invoke(o, null);
}
}
}
The type casting of object o to Stack works because the type is predefined and compiler has no issue is finding the standard definition or maybe binding works by default. I can even invoke print method on the object. Another interesting observation is that there is no object slicing happening in C# unlike C++. This is because the everything is passed by reference in C# (thanks to Abhinab who pointed out the reason).