2010-07-27 20 views
5

Stworzyłem typ tak:Dlaczego IsAssignableFrom i GetInterface dać różne wyniki

TypeBuilder tb = moduleBuilder.DefineType(myname, TypeAttributes.Class | 
     TypeAttributes.Public, typeof(BaseClass), new Type[] { typeof(ImyInterface) }); 

Wtedy dużo kodu ilgenerating następująco dla konstruktorów, metod itp Kiedy zacznę pomocą klasy zauważyłem coś dziwnego. Chcę sprawdzić, czy typ "myname", który stworzyłem, naprawdę implementuje ImyInterface. Spodziewam się, że oba z poniższych stwierdzeń return true:

// t is Type 'myName' 
Type baseInterface = t.GetInterface(typeof(ImyInterface).name); 
if (baseType != null) 
{ 
    // this is actually true, as I expected 
} 

if (typeof(ImyInterface).isAssignableFrom(t)) 
{ 
    // the if clause is false, but I don't have a clue why?? 
} 

Więc stworzyliśmy klasa, która implementuje ImyInterface ale które nie jest przypisane do obiektu typu ImyInterface, czego mi brakuje?

Nawiasem mówiąc, nie ma udział leków generycznych, a interfejs jest po prostu podstawowy jeden przetestować koncepcję:

public interface ITestInterface 
{ 
    int CalcSquaredInteger(int number); 
} 
+0

Czy są zaangażowane leki generyczne? w jaki sposób deklarowany jest interfejs? –

+0

Brak generycznych, dodałem przykładowy interfejs do tego pytania. – Yodah

+0

Co to jest "ImyInterface" w powyższym kodzie? Biorąc pod uwagę, że wywołujesz na niej "nazwę" usługi, nie może to być po prostu interfejs? –

Odpowiedz

2

i wreszcie dowiedział się, co mi brakuje: Kiedy jesteś sprawdzanie typu com łatwość i możliwość przypisania między typami i interfejsami, które zdefiniowałeś w różnych projektach/złożeniach, następnie upewnij się, że wszystkie Twoje projekty są podpisane i mocno nazwane !! W przeciwnym razie metoda GetInterface zadziała, ponieważ tylko porównuje nazwę. Ale .net nie będzie przypisywał między typami.

+0

Domyślam się, że nazwa jest wystarczająco silna, podpisywanie nie powinno mieć znaczenia w twoim scenariuszu. Btw: Zauważyłem, że implementacja IsAssignableFrom jest zupełnie inna w .NET 3.5 i 4.0. Z jakiej wersji korzystałeś? – Abel

+0

Masz rację, silnie nazywane za mało! Używam 3.5, dziękuję za wskazanie tego. Wstawię listę rzeczy do zrobienia, aby sprawdzić zachowanie w wersji 4.0 – Yodah

1
using ClassLibrary1; // this is another project that contains IMyInterface 

namespace ConsoleApplication1 
{ 
    public class MyBaseClass 
    { 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      MyReflectionTest(typeof(ClassLibrary1.IMyInterface)); 
     } 

     private static void MyReflectionTest(Type interfaceType) 
     { 

      AssemblyName aName = new AssemblyName("DynamicAssemblyExample"); 
      AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave); 

      ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); 

      TypeBuilder tb = mb.DefineType("MyDynamicType", TypeAttributes.Public, typeof(MyBaseClass), new Type[] { interfaceType }); 

      MethodBuilder mbIM = tb.DefineMethod("IMyInterface.MyTestMethod", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, null, Type.EmptyTypes); 
      ILGenerator il = mbIM.GetILGenerator(); 
      il.Emit(OpCodes.Ret); 

      tb.DefineMethodOverride(mbIM, interfaceType.GetMethod("MyTestMethod")); 

      var myType = tb.CreateType(); 

      Debug.Assert(interfaceType.IsAssignableFrom(myType) == true); 
     } 
    } 
} 

to działa, więc sądzę, że problemem jest gdzieś w kodzie nie zrobił” t tutaj po

edit: zaktualizowane tak IMyInterface jest teraz w innym projekcie, a nadal działa

+0

"to działa, więc myślę, że problem jest gdzieś w kodzie, którego tu nie zamieściłeś", dobrze, że wniosek jest oczywiście słuszny. Dziwne jest to, że mój kod jest podobny do twojej próbki. Jedyną różnicą jest to, że typ interfejsu (IMyInterface w twoim przykładzie) w moim przypadku jest parametrem metody, która wykonuje całe tworzenie zestawu/typu. Ten typ jest zdefiniowany w innej przestrzeni nazw/projekcie, więc kopie tam, aby sprawdzić, czy to ma znaczenie. Kiedy wycinam i wklejam interfejs i zakodowuję go w bieżącej przestrzeni nazw, to działa, ale to nie jest to, czego potrzebuję ... – Yodah

Powiązane problemy