简体   繁体   中英

Strange behavior of type casting

I'm trying create some type from assembly. That type implements interface IDerrivedInterface , which inherits from interface IBaseInterface . So, I'm going to create instance of type, that implements IBaseInterface :

if (assembly != null)
{
     ObjTypes = assembly.GetTypes(); 
     foreach (var objType in ObjTypes)
     {
         try
         {
             var type = Activator.CreateInstance(objType);
             if (type is IBaseInterface)
             {
                  list.Add((IBaseInterface) type);                
             }
         }
         catch (Exception ex)
         {
             int a = 0;
         }
     }
}

There is type, which implements IDerrivedInterface in assembly . But the line of code list.Add((IBaseInterface) type) is not executed. I was trying to debug this: I added type is IBaseInterface to "Watches" and that value was True . What is the reason of that behavior?

UPD: list - is simple List<>. I think it does not matter. No exception is thrown. IDerrived interface inherits from IBaseInterface :

interface IBaseInterface
{
//
}
interface IDerrivedInterface : IBaseInterface
{
}
//and a class in assembly:
class SomeType : IDerrivedInterface
{
}

UPD2: The assembly is loaded from some folder. There are several assemblies and several other files in that folder. I am iterating through all files with a ".dll" extension. Then I collect all the objects whose type implements IBaseInterface to the list. My type (which implements IBaseInterface ) and the declaration of IBaseInterface are placed in different assemblies. So, if there is no assembly (which contains the declaration of IBaseInterface ), it works. But if there is that assembly (and it processed before assembly with Type) it does not work.

UPD3: There are several different interfaces, which implement that type. Moreover, that type is derivied from some BaseClass . It should work, but it doesn't..

Here is some question about another error, but there is one aswer about accesing two assemblies in different contexts. Maybe it is my case. Because the Library (let it be "L1") has reference to the Library (L2), where the declaration of the interfaces is placed. And there is one more library (L3), which contains the declaration of class, that implements interfaces from L2 (thats why L3 has reference to L2 too). So I am debugging in L1 (which has a reference to L2) and it loads the assemblies L2 and L3). Maybe that is why I have this problem..

The assembly would contain the three types IBaseInterface,IDerrivedInterface and a class implementing the IDerrivedInterface. The line

          var type = Activator.CreateInstance(objType);

will throw exception as you can not create an object of type interface.Since a variable of interface type can hold the reference of the object of the class implementing the interface but can not be an object it self. For the class the code

        if (type is IBaseInterface)
         {
              list.Add((IBaseInterface) type);                
         }

will be executed successfully provided that the list is of IBaseInterface.

Edited: Adding the code.

I made a ClassLibrary as below.

namespace ClassLibrary
{
    public interface IBaseInterface
    {
    }
    public interface IDerivedInterface : IBaseInterface
    {
    }

    public class Class1:IDerivedInterface
    {

    }
}

And in Another project i executed following code.

        List<IBaseInterface> list = new List<IBaseInterface>();
        var assembly = System.Reflection.Assembly.LoadFrom("ClassLibrary.dll");
        if (assembly != null)
        {
            var ObjTypes = assembly.GetTypes();
            foreach (var objType in ObjTypes)
            {
                try
                {
                    var type = Activator.CreateInstance(objType);
                    if (type is IBaseInterface)
                    {
                        list.Add((IBaseInterface)type);
                    }
                }
                catch (Exception ex)
                {
                    int a = 0;
                }
            }
        }

It throws exception for the first two interfaces and added an item for the class type.

As I understand, the problem is that the line list.Add((IBaseInterface) type); does not get executed.

Are you sure that your IDE (I guess Visual Studio) is set on DEBUG and not RELEASE? Maybe you just don't see it gets executed.

Also maybe you have an exception there and you catch it somewhere else. If that if contains a TRUE, then it must go inside the if statement.

So I resolve it using post-build event and copying only 1 dll to subfolder(where program search DLL with types). Before that, there were several dependent DLLs, that as I understand give me wrong behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM