Bir sınıfta bir özellik olup olmadığını kontrol edin


83

Bir sınıfta bir özellik olup olmadığını öğrenmeye çalışıyorum, şunu denedim:

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

İlk test yönteminin neden başarılı olmadığını anlamıyorum?

[TestMethod]
public void Test_HasProperty_True()
{
    var res = typeof(MyClass).HasProperty("Label");
    Assert.IsTrue(res);
}

[TestMethod]
public void Test_HasProperty_False()
{
    var res = typeof(MyClass).HasProperty("Lab");
    Assert.IsFalse(res);
}

4
İlgili kodu adresinden gönderebilir misiniz MyClass?
nattyddubbs

Yanıtlar:


128

Yönteminiz şuna benzer:

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

Bu object, her şeyin temel sınıfına bir uzantı ekler . Bu uzantıyı aradığınızda, onu a Type:

var res = typeof(MyClass).HasProperty("Label");

Kişisel yöntemi bir bekler örneği bir sınıf değil, bir bir Type. Aksi takdirde esasen yapıyorsun

typeof(MyClass) - this gives an instanceof `System.Type`. 

Sonra

type.GetType() - this gives `System.Type`
Getproperty('xxx') - whatever you provide as xxx is unlikely to be on `System.Type`

@PeterRitchie'nin doğru bir şekilde işaret ettiği gibi, bu noktada kodunuz Labelüzerinde mülk arıyor System.Type. Bu özellik mevcut değil.

Çözüm ya

a) Uzantıya bir MyClass örneği sağlayın :

var myInstance = new MyClass()
myInstance.HasProperty("Label")

b) Uzantıyı açın System.Type

public static bool HasProperty(this Type obj, string propertyName)
{
    return obj.GetProperty(propertyName) != null;
}

ve

typeof(MyClass).HasProperty("Label");

2
yani, kodunuz` Type.Label , not MyClass.Label` aranıyor .
Peter Ritchie

Bu, System.Type uzantısına nasıl yerleştirilir, nerede bulunurdu /. Bu, çalıştırılacak kodda nereye gider?
Demodave

1
@Demodave - genişletme yöntemleri yalnızca genel bir statik sınıftadır. Daha fazla bilgi için buraya bakın: msdn.microsoft.com/en-GB/library/bb383977.aspx
Jamiec

Şu hatayı alırsanız: "Tür, GetProperty için bir tanım içermiyor" o zaman şunu okuyun: stackoverflow.com/questions/7858469/…
Tadej

27

Bu, farklı bir soruyu yanıtlar:

Bir OBJECT'in (sınıfın değil) bir özelliği olup olmadığını anlamaya çalışıyorsanız,

OBJECT.GetType().GetProperty("PROPERTY") != null

özellik varsa (ancak yalnızca değilse) doğru döndürür.

Benim durumumda, bir ASP.NET MVC Kısmi Görünümündeydim ve özellik yoksa veya özellik (boolean) doğruysa bir şey oluşturmak istedim.

@if ((Model.GetType().GetProperty("AddTimeoffBlackouts") == null) ||
        Model.AddTimeoffBlackouts)

burada bana yardım etti.

Düzenleme: Günümüzde, nameoftelli özellik adı yerine operatörü kullanmak muhtemelen akıllıca olacaktır .


nameofOperatörün kullanımıyla ilgili olarak, var olmayan bir mülkün adını almak işe yarayacak mı (bir istisna atılmayacak) mı? İlk sorunun dayanağı, bu özelliğin var olup olmadığını bilmediğimizden beri?
Zoe

Neden denemiyorsun ve sonra açıklığa kavuşturmak için cevabımı düzenlemiyorsun?
Stachu

2

2 olasılık vardır.

Gerçekten Labelmülkün yok.

Uygun GetProperty aşırı yüklemesini çağırmanız ve doğru bağlama bayraklarını iletmeniz gerekir , örn.BindingFlags.Public | BindingFlags.Instance

Mülkünüz halka açık değilse BindingFlags.NonPublic, kullanım durumunuza uyan bayrakların başka bir kombinasyonunu kullanmanız gerekecektir . Ayrıntıları bulmak için başvurulan API belgelerini okuyun.

DÜZENLE:

ooops, sadece aramak fark ettim GetPropertyüzerinde typeof(MyClass). typeof(MyClass)kesinlikle Typehiçbir Labelmülkü olmayan .


Kullanılan varsayılan bağlama bayrakları Instance|Public|Static, iirc'dir.
LukeH

@LukeH, emin değildim, bu yüzden 'doğru' yazdım ve 'örneğin' ekledim :) belki Labelözel mülkiyettir.
Zdeslav Vojkovic

1

Şu hatayı aldım: Kabul edilen yanıtı bağlarken "Tür GetProperty için bir tanım içermiyor".

Bu benim sonucum:

using System.Reflection;

if (productModel.GetType().GetTypeInfo().GetDeclaredProperty(propertyName) != null)
{

}

0

Benim gibi bağlayıcıysan:

<%# Container.DataItem.GetType().GetProperty("Property1") != null ? DataBinder.Eval(Container.DataItem, "Property1") : DataBinder.Eval(Container.DataItem, "Property2")  %>

0

Bunun neden gerekli olduğuna dair bağlamdan emin değilim, bu yüzden bu size yeterli bilgi vermeyebilir, ancak bunu yapabildim:

if(typeof(ModelName).GetProperty("Name of Property") != null)
{
//whatevver you were wanting to do.
}

Benim durumumda, bir form gönderiminden özellikler üzerinden çalışıyorum ve ayrıca giriş boş bırakılırsa kullanacağım varsayılan değerlere sahibim - bu yüzden kullanılacak bir değer olup olmadığını bilmem gerekiyordu - modeldeki tüm varsayılan değerlerimin önüne ekledim Varsayılan ile yapmam gereken tek şey, bununla başlayan bir özellik olup olmadığını kontrol etmekti.

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.