Bir nesnenin belirli bir yöntemi / özelliği olup olmadığını nasıl kontrol edebilirim?


155

Dinamik desen mi kullanıyorsunuz? Dinamik anahtar kelimeyi kullanarak herhangi bir yöntemi / özelliği çağırabilirsiniz, değil mi? Örneğin, myDynamicObject.DoStuff () yöntemini çağırmadan önce yöntemin var olup olmadığını nasıl kontrol edebilirim?


MyDynamicObject türü nedir ? Bu türetilmiş bir sınıf DynamicObjectmı?
Cheng Chen

anahtar kelimesi ile bildirilen bir şey
Louis Rhys

Yanıtlar:


224

Böyle bir şey yazabilirsiniz:

public static bool HasMethod(this object objectToCheck, string methodName)
{
    var type = objectToCheck.GetType();
    return type.GetMethod(methodName) != null;
} 

Düzenleme: Hatta bir uzantı yöntemi yapabilir ve bu şekilde kullanabilirsiniz

myObject.HasMethod("SomeMethod");

GetType () çalışma zamanı türünü döndürür? (yani itiraz değil mi?)
Louis Rhys

2
evet, GetType () çalışan türü döndürürken typeof () nesneyi döndürür.
Julien

1
Belgelere göre GetType () "Geçerli örneğin tam çalışma zamanı türü" döndürür.
tzup

Ayrıca, uzantı yönteminin statik olması gerekir.
Fraser

9
Yazmayı tercih ederim: objectToCheck.GetType (). GetMethod (methodName)! = Null
efirat

85

Yansıma yoluyla

 var property = object.GetType().GetProperty("YourProperty")
 property.SetValue(object,some_value,null);

Benzer yöntemler için


Güzel. Uygun tanımlanmış özelliği almak için bir döngüde GetMethod da yapabilirsiniz.
Jnr

Bağlantılı UI kontrol listeleri ve Ebeveynleri arasında
geçiş yapmak için kullanışlıdır

İçinde GetType()gibi bir yöntem var GetProperties(). Dizisini döndürüyor PropertyInfo. Ancak GetProperties()yöntemi nasıl kullanabilirim ?
Yogesh Patel

43

Bu eski bir soru, ama ben sadece onunla karşılaştım. Type.GetMethod(string name)bu ada sahip birden fazla yöntem varsa bir AmbiguousMatchException kurar, bu nedenle bu durumu daha iyi ele alırız

public static bool HasMethod(this object objectToCheck, string methodName)
{
    try
    {
        var type = objectToCheck.GetType();
        return type.GetMethod(methodName) != null;
    }
    catch(AmbiguousMatchException)
    {
        // ambiguous means there is more than one result,
        // which means: a method with that name does exist
        return true;
    }
} 

18

Bunun için herhangi bir dinamik tür kullanmamak ve sınıfınızın bir arayüz uygulamasına izin vermek daha iyi olmaz mıydı? Ardından, çalışma zamanında bir nesnenin bu arabirimi uygulayıp uygulamadığını ve dolayısıyla beklenen yönteme (veya özelliğe) sahip olup olmadığını kontrol edebilirsiniz.

public interface IMyInterface
{
   void Somemethod();
}


IMyInterface x = anyObject as IMyInterface;
if( x != null )
{
   x.Somemethod();
}

Bence bu tek doğru yol.

Bahsettiğiniz şey, nesnenin yönteme sahip olduğunu zaten bildiğiniz senaryolarda yararlı olan ördek yazmadır, ancak derleyici bunu kontrol edemez. Bu, örneğin COM birlikte çalışma senaryolarında kullanışlıdır. ( bu makaleye bakın)

Ördek yazmayı yansıma ile birleştirmek istiyorsanız, o zaman ördek yazmanın amacını kaçırdığınızı düşünüyorum.


2
nesne .NET framework tarafından sağlanan bir nesne olabilir ve ben bir şey uygulamak için ilan edemez?
Louis Rhys

Sorun ne ? .NET nesnesi tarafından aynı şekilde sağlanan 'nesnenin' böyle bir nesne olup olmadığını kontrol edebilirsiniz
Frederik Gheysels

örneğin, bir nesnede "Ekle" yöntemi olup olmadığını kontrol etmek istersiniz. Ve nesne bir Liste <int> veya IEnumerable olmayan başka bir sınıf olabilir
Louis Rhys

3
Belki de bir Adobe ürününü COM ile kodlamaya bir göz atmalısınız. Aynı işlev çağrısı tamamen farklı COM nesnelerini döndürebilir ve (Adobe) tasarımı ile tek ortak ataları nesnedir. Ayrıca: Bu hemen hemen tüm modern dinamik komut dosyası dillerinde (Python, Javascript, VB komut dosyası, PHP, Lua ... devam edebilirim) sıradan bir modeldir. Bu bir hata değil, bir özelliktir.
Tim Keating

5
Bir koku ama microsoft tarafından yaratıldı. Button, LinkButton, vs. gibi WebControls'e bakın. İkisi de OnClientClick özelliğini uygularlar, diyelim ki ListControl ve Panel bunu yapmaz. OnClientClick bir arabirimde tanımlanmadığından yansıma tek seçenektir.
HammerIp
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.