2009-10-28 7 views
9

Bir tür ve bir arabirim var ve türün arabirimi soyut olarak uyguladığını doğrulamam gerekiyor.Bir .NET türünün belirli .NET arabirimini soyut olarak uygulayıp uygulamadığı nasıl denetlenir?

Yansıma kullanarak kaba kuvvet kodu yazmayı ayarlıyorum ve oldukça çirkin.

Şu an yaptığım kaba kuvvet uygulamasından daha iyi bir yol olup olmadığını merak ediyorum.

Herhangi bir fikrin var mı?

Teşekkürler.

DÜZENLEME

henüz uygulamaya kullanıma değil ama kaba kuvvet taslak kodu şöyle : Kod sahip olduğunu, zaten özelliklere sahip bir sorun görüyor bunu derleme olmadan

public static bool IsAbstractInterfaceImplementation(Type someType, Type someInterface) 
    { 
    if (!someInterface.IsAssignableFrom(someType)) 
    { 
     return false; 
    } 

    if (!someType.IsAbstract) 
    { 
     return false; 
    } 

    var m_interfaceMemberNames = someInterface.GetMembers().Select(m => m.Name).ToList(); 
    // Make sure every interface member implementation is abstract. 
    foreach (var typeMember in someType.FindMembers(MemberTypes.Event | MemberTypes.Property | MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance, null, null)) 
    { 
     if (m_interfaceMemberNames.Contains(typeMember.Name)) 
     { 
     MethodInfo method; 
     // Make sure the ancestor member is abstract. 
     switch (typeMember.MemberType) 
     { 
     case MemberTypes.Event: 
      if (!IsAbstractImplementation(((EventInfo)typeMember).GetAddMethod())) 
      { 
      return false; 
      } 
      method = ((EventInfo)typeMember).GetRemoveMethod(); 
      break; 
     case MemberTypes.Property: 
      method = ((PropertyInfo)typeMember).GetGetMethod(); 
     default: 
      method = (MethodInfo)typeMember; 
      break; 
     } 
     if (!IsAbstractImplementation(method)) 
     { 
      return false; 
     } 
     } 
    } 
    return true; 
    } 

    public static bool IsAbstractImplementation(MethodInfo methodInfo) 
    { 
    const MethodAttributes expectedAttributes = 
     MethodAttributes.Abstract | 
     MethodAttributes.Public | 
     MethodAttributes.NewSlot | 
     MethodAttributes.Virtual; 

    return (methodInfo.Attributes & expectedAttributes) == expectedAttributes; 
    } 

arayüzün alıcı ve/veya ayarlayıcıyı tanımlayıp tanımlamadığını ve körü körüne alıcıyı kabul etmek yerine, doğru yöntemi (yöntemleri) doğrulayıp doğrulamadığını kontrol etmek için. Neyse, görebildiğimiz gibi, kod oldukça sıkıcı. daha iyi bir yolu olup olmadığını

DÜZENLEME ... merak ediyorum 2

  • Bu sadece bir taslak uygulama olduğunu, stres isteyen, basit durumlar için çalışır ve daha fazlası için bozuldu Karmaşık olanlar, yöntem aşırı yükleri veya yöntem yeniden adlandırmaları gibi (Ben VB bilmiyorum, bu yüzden mümkün olduğunu bile düşünmedim). Ancak, doğru yapmak için çok çalışma gerektirdiğini vurgulamak isterim.
  • Neden böyle bir şey isterim? Dinamik olarak edinilmiş bazı meta verilere dayanarak Reflection.Emit'i kullanarak dinamik olarak türler oluşturmamız gerekiyor. Oluşturulan dinamik tip, IDynamicObject gibi belirli arabirimleri uygular ve bazı atalardan türetilebilir. Bu ata tipi statik olarak derlenir. Yakın zamana kadar, atası türünün IDynamicObject arabirimini uygulamalarına izin verilmedi. Dinamik türün bir örneği verildiğinde, yöntemlerine erişim sağlamak için açık bir şekilde IDynamicObject'e dökülmelidir (hatırlayın, oluşturulan dinamik türün arabirimi gerçekleştirdiğinden emin olun). Bu açık kadroları ortadan kaldırmak istiyorum. Bunu yapmanın tek yolu, atalayıcının türünün IDynamicObject arabirimini kullanmasına izin vermektir. Ancak, uygulama, dinamik tip oluşturma koduyla doğrulanan tüm soyut olmalıdır. Voila.
+0

"Yansıma kullanarak kaba kuvvet kodu" - yükleyebilir misiniz? –

+0

Tam olarak ne anlama geliyor "ne tür soyut arabirimi uygular"? – LBushkin

+0

Tamam, çalıştığından emin olmak için birkaç dakika. – mark

cevap

27

tip Type.IsAssignableFrom kullanarak belirli bir arayüz uygulayan olmadığını belirleyebilirsiniz:

typeof(MyInterface).IsAssignableFrom(abstractType); 

Düzenleme: açıklama sonra cevap eklendi - Bir arabirimin uygulamaların tümü için soyut olup olmadığını belirlemek için

bool IsAbstractOfInterface(Type classType, Type interfaceType) 
{ 
    var map = classType.GetInterfaceMap(interfaceType); 
    foreach (var info in map.TargetMethods) 
    { 
     if (!info.IsAbstract) 
     { 
      return false; 
     } 
    } 
    return true; 
} 
: Belirli bir sınıf, söz konusu türü için bir InterfaceMap alarak çok daha kolayca yapabilirsiniz

Ya da genel bir uzantı yöntemi ...

public static bool IsAbstractOf<TInterface>(this Type type) 
{ 
    var map = type.GetInterfaceMap(typeof(TInterface)); 
    foreach (var info in map.TargetMethods) 
    { 
     if (!info.IsAbstract) 
     { 
      return false; 
     } 
    } 
    return true; 
} 
+0

Bu türün arabirimi uyguladığı bilinmektedir. İhtiyacım olan şey, uygulamanın tamamen soyut olup olmadığı. – mark

+0

@Mark, her bir üyeyi soyut olup olmadığını görmek için yansıtmadan bilmenin bir yolu yoktur. –

+0

Şüpheleniyorum. Ama farkında olmadığım yansıma ile ilgili hileler var olabilir. – mark

1

Rex M'in cevabı genel olarak doğru ama senin tipin bir tür parametresi ise, ayrıca yapabilirsiniz:

class Foo<T> where T : IWhatever { 
    // Do your thing, secure in the knowledge that T implements IWhatever 
} 
+0

Bu türün arabirimi uyguladığı bilinmektedir. İhtiyacım olan şey, uygulamanın tamamen soyut olup olmadığı. – mark

1
public static bool IsAbstractInterfaceImplementation(Type someType, Type someInterface) 
{ 
    return someType.IsAbstract && someInterface.IsAssignableFrom(someType); 
} 
+0

Bu sadece sınıfın soyut olup olmadığını, belirli yöntemlerin soyut olup olmadığını belirler. –

0

Sen üyesi adlarını kullanamazsınız. Varsayalım ki, bir üyenin adı, uyguladığı arayüz üyesi hakkında bir şey söyler. Yansıma, hangi yöntemin arabirimden hangisini uygulayacağını görmek için araçlar sağlar.

Belirli bir türde tüm yöntemi yalnızca soyut olarak uygulanan bir parçacığı olan bir kod parçacığı.