Nesnenin arayüzü uygulayıp uygulamadığını test edin


Yanıtlar:


570
if (object is IBlah)

veya

IBlah myTest = originalObject as IBlah

if (myTest != null)

85
+1 İkincisi daha iyi çünkü muhtemelen ilkiyle birlikte atmanız gerekecek ve böylece size iki oyuncu ("is" ve sonra açık bir oyuncu) vereceksiniz. İkinci yaklaşımla sadece bir kez atıyorsunuz.
Andrew Hare

51
@Andrew: +1; Julian M Bucknall'ın klasik Double-Casting AntiPattern blog yazısı bağlantısı için bir kez daha .
Jeroen Wiert Pluimers

1
Optimizasyon muhtemelen ilk durumda iki kez yayınlamayacak mısın?
BuZz

1
@Joreen, "as" kullanamayacağınız bir yapıyla çalışıyorsanız bu bağlantı bir noktayı kaçırır, çünkü "as" döndürmeye çalıştığı boş bir değer tutmaz, bu durumda bir nulllable int gibi sınıf, ama her zaman referans türleri olarak sadece arayüz düzeyinde çalışan bir sorun değil
MikeT

46
C # 6.0'dan beri:if (object is IBlah iblah) { iblah.SomeMethod(); }
Knelis

224

Derleme zamanında arabirim türünü biliyorsanız ve sınadığınız türün bir örneğine sahipseniz isveya asişleçlerini kullanmak doğru yoldur. Kimsenin bahsetmediği bir şey Type.IsAssignableFrom:

if( typeof(IMyInterface).IsAssignableFrom(someOtherType) )
{
}

Ben bu döndü dizi bakarak daha temiz GetInterfacesve sınıflar için de çalışma avantajı olduğunu düşünüyorum .


Bir tipin IList örneğini uygulayıp uygulamadığını belirlemeye çalışıyorum. "Typeof (IList <>). IsAssignableFrom (someType)" kullanıyorum ama bu çalışmıyor.
KeyboardDrummer

3
Bunu başka bir soruda sormak daha iyi olabilir. SomeType, liste öğelerinin türüyse typeof (IList <>) öğesine ihtiyacınız olabilir. MakeGenericType (someType). SomeType liste türüyse, Type.GetGenericArguments ve Type.GetGenericTypeDefinition öğelerine bakmanız gerekir.
Andrew Kennan

Bunu bir eklenti sisteminde tip kontrolü için kullanıyorum. Nesnenin bir örneğinin henüz bulunmadığı durumlarda kullanılabilir. Ama yaptığım şeye bağlı olarak hem bu stili hem de Robert'ı kullanıyorum, bu yüzden her iki yöne de oy verdim.
James

Bu eski bir yorumdur, ama Steenreem sorusuna, kullanım @ cevaba typeof(IList).IsAssignableFrom(someType)olmadan <>.
saluce

Bu yöntem, dönüştürme operatörleriyle bile çalışır ve TypeConverters söz konusu olduğunda
Harald Coppoolse

22

Örneğin:

if (obj is IMyInterface) {}

Sınıf için:

typeof(MyClass).GetInterfaces()Arayüzü içerip içermediğini kontrol edin .


1
if (Array.IndexOf (typeof (MyClass) .GetInterfaces (), typeof (IMyInterface))! = -1) {...}
Constantin

2
veya: if (typeof (MyClass) .GetInterfaces (). İçerikler (typeof (IMyInterface))) {...}
Lance Fisher


16

@ AndrewKennan'ın cevabındaki bir varyasyon, çalışma zamanında elde edilen türler için son zamanlarda kullandım:

if (serviceType.IsInstanceOfType(service))
{
    // 'service' does implement the 'serviceType' type
}

7

Bu yazı iyi bir cevap.

public interface IMyInterface {}

public class MyType : IMyInterface {}

Bu basit bir örnektir:

typeof(IMyInterface).IsAssignableFrom(typeof(MyType))

veya

typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))

3

"İs" operatörünü kullanarak test etmeye ek olarak, kendisine iletilen değişkenlerin aşağıdaki gibi belirli bir arayüz uyguladığından emin olmak için yöntemlerinizi dekore edebilirsiniz:

public static void BubbleSort<T>(ref IList<T> unsorted_list) where T : IComparable
{
     //Some bubbly sorting
}

Bu sürümün hangi sürümü uygulandığından emin değilim, bu yüzden sürümünüzde çalışmayabilir.


2
.net 2.0 jenerikler ekledi.
Robert C. Barth

Bu konudaki tek derleme zamanı kontrolü, teşekkürler.
Dustin Malone

2

Benim için işe yarayan:

Assert.IsNotNull(typeof (YourClass).GetInterfaces().SingleOrDefault(i => i == typeof (ISomeInterface)));


1

Son zamanlarda Andrew Kennan'ın cevabını kullanmayı denedim ve bir nedenden dolayı benim için işe yaramadı. Bunun yerine kullandım ve işe yaradı (not: ad alanını yazmak gerekli olabilir).

if (typeof(someObject).GetInterface("MyNamespace.IMyInterface") != null)

2
Bu yolu gidiyor, ben sihirli dizeleri hayranı değilim, bu yüzden en azından bu tür typeof (IMyInterface) .Name yerine "MyNamespace.IMyInterface" değiştirmek istiyorum. Yeniden düzenleme kanıtını bir bonus olarak adlandırmaya yardımcı olur.
greyalien007

0

kullandım

Assert.IsTrue(myObject is ImyInterface);

myObject öğesinin ImyInterface arayüzümü uygulayan bir nesne olduğunu test eden birim testim için.


-1

Bir yönteme değişken geçirdiğim bir durum vardı ve bir arabirim mi yoksa nesne mi olacağından emin değildim.

Hedefler:

  1. Öğe bir arabirim ise, arabirimi yapıcı çağrısında bir parametre olacak şekilde, bu arabirime dayalı bir nesne başlatın.
  2. Öğe bir nesneyse, çağrılarımın oluşturucusu bir arabirim beklediğinden ve kodun depolanmasını istemediğimden bir boş döndürün.

Bunu aşağıdakilerle başardım:

    if(!typeof(T).IsClass)
    {
       // If your constructor needs arguments...
       object[] args = new object[] { my_constructor_param };
       return (T)Activator.CreateInstance(typeof(T), args, null);
    }
    else
       return default(T);

-12

Bu çalışmalı :

MyInstace.GetType().GetInterfaces();

Ama güzel de:

if (obj is IMyInterface)

Ya da (çok zarif değil):

if (obj.GetType() == typeof(IMyInterface))

9
Typeof (IMyInterface) ile eşitliği kontrol etmek her zaman başarısız olur. Downvoted.
Jay Bazuzi

Sağ. Arayüz örneği yok.
Rauhotz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.