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.