Question

Imagine I have a visual studio solution containing two projects. In this scenario, Project 1 is aware of Project 2, but Project 2 is NOT aware of Project 1.

Project 1

using Project2;

namespace Project1
{
   public class ClassA : IMyInterface {}

   public class Main {

       public void MainMethod()
       {
           ARandomClass aRandomClass = new ARandomClass();
           IMyInterface classA = new ClassA();
           aRandomClass.MyItem = classA;
           aRandomClass.MyMethod();
       }

   }
}

Project 2

namespace Project2
{
   public interface IMyInterface { }

   public class ARandomClass {
      public IMyInterface MyItem { get; set; }

      public void MyMethod() {
         Type type = MyItem.GetType(); // what happens here?
      }
   }
}

My question really is what would happen if we try to get the type of an object inside a project that has no reference/knowledge of that type?

Would it return the interface? Can it? Is it somehow able to reference the type? Would it return "object"? Or would it do something else entirely?

Was it helpful?

Solution

It would return the actual type ClassA.

All the type information is available and inspectable via reflection. You simply can't directly reference the type at compile-time.

Project 2 could still call members on ClassA, it would just be difficult/cumbersome because you would be limited to using reflection or dynamic.

public void MyMethod() {
    Type type = MyItem.GetType(); //gets a `System.Type` representing `ClassA'
    Console.WriteLine(type.FullName);//outputs "Project1.ClassA"
}

Just do demonstrate what you can or cannot do, say ClassA was defined as:

public class ClassA : IMyInterface 
{
    public string MyField = "Hello world!";
}

You would not be able to do this:

public void MyMethod() {
    Console.WriteLine(MyItem.MyField); //compiler error
}

You could do this because Project2 can access information from Project1 at runtime:

public void MyMethod() {
    //lookup the field via reflection
    Type type = MyItem.GetType();
    Console.WriteLine(type.GetField("MyField").GetValue(MyItem));

    //simpler way than above using dynamic, but still at runtime
    dynamic dynamicItem = MyItem;
    Console.WriteLine(MyItem.MyField);
}

But you couldn't do this because Project2 has no knowledge of Project1 at compile time:

public void MyMethod() {
    //cast to type ClassA
    ClassA classAMyItem = (ClassA)MyItem; //compile error
    Console.WriteLine(classAMyItem.MyField); //compile error
}

This is basically one of the tenants of polymorphism though. Your MyMethod shouldn't know, and shouldn't care what class MyItem is beyond it being an IMyInterface. It should generally only care about accessing the properties, methods, and events as defined on IMyInterface. If it does care about it being an instance of ClassA, then you might want to reconsider your design or usage.

OTHER TIPS

You will get the type as Project1.ClassA

The code you see in Project 2 is still going to be run from Project 1, that's where your call is and therefore will be able to give you the correct information about what the type that Interface is.

My guess would be the output will be something like Project1.ClassA with whatever you have before it. But to be sure just run that code and see what output you get

public void MyMethod() {
         Type type = MyItem.GetType(); // what happens here?
      }

type variable will point to your AClass. You can change your code to looks like this:

   public IMyInterface MyMethod()
        {
            Type type = MyItem.GetType(); // what happens here?
            IMyInterface value = (IMyInterface)Activator.CreateInstance(type);
            return value;
        }

Now you can use instance of your class using interface without much of reflection (Activator is using reflection inside to create an instance).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top