97

我试图知道一个属性是否存在于一个类中,我试过这个:

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

我不明白为什么第一个测试方法不通过?

[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

6 回答 6

150

您的方法如下所示:

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

这在一切object的基类上添加了一个扩展。当您调用此扩展程序时,您将其传递给:Type

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

您的方法需要一个类的实例,而不是一个Type. 否则你基本上在做

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

然后

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

正如@PeterRitchie 正确指出的那样,此时您的代码正在寻找Label. System.Type该属性不存在。

解决方案是

a) 为扩展提供一个 MyClass的实例:

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

b) 把扩展放在System.Type

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

typeof(MyClass).HasProperty("Label");
于 2013-03-11T14:33:14.717 回答
28

这回答了一个不同的问题:

如果试图弄清楚一个 OBJECT(不是类)是否有一个属性,

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

如果(但不仅是)该属性存在,则返回 true。

在我的例子中,我在一个 ASP.NET MVC 部分视图中,如果属性不存在或者属性(布尔值)为真,我想渲染一些东西。

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

在这里帮助了我。

编辑:如今,使用nameof运算符而不是字符串化的属性名称可能很聪明。

于 2013-12-18T15:00:16.807 回答
3

我收到此错误:“类型不包含 GetProperty 的定义”在绑定接受的答案时。

这就是我最终得到的:

using System.Reflection;

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

}
于 2017-05-17T07:20:01.937 回答
2

有2种可能性。

你真的没有Label财产。

您需要调用适当的GetProperty 重载并传递正确的绑定标志,例如BindingFlags.Public | BindingFlags.Instance

如果您的财产不是公开的,您将需要使用BindingFlags.NonPublic适合您的用例的标志或其他一些标志组合。阅读引用的 API 文档以查找详细信息。

编辑:

哎呀,刚刚注意到你打电话GetProperty。是肯定没有财产的。typeof(MyClass)typeof(MyClass)TypeLabel

于 2013-03-11T14:29:13.353 回答
0

如果您像我一样具有约束力:

<%# Container.DataItem.GetType().GetProperty("Property1") != null ? DataBinder.Eval(Container.DataItem, "Property1") : DataBinder.Eval(Container.DataItem, "Property2")  %>
于 2015-04-22T15:26:31.400 回答
0

我不确定为什么需要这样做的上下文,所以这可能无法为您返回足够的信息,但这是我能够做到的:

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

在我的情况下,我正在运行表单提交中的属性,并且如果条目留空,则还有要使用的默认值 - 所以我需要知道是否有要使用的值 - 我在模型中添加了所有默认值的前缀使用Default所以我需要做的就是检查是否有一个以它开头的属性。

于 2018-04-09T12:36:47.060 回答