检查类中是否存在属性

时间:2013-03-11 14:26:20

标签: c# .net reflection

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

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);
}

6 个答案:

答案 0 :(得分:94)

您的方法如下:

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");

答案 1 :(得分:16)

这回答了另一个问题:

如果试图找出OBJECT(非类)是否具有属性,

OBJECT.GetType().GetProperty("PROPERTY") != null
如果(但不仅仅是)属性存在,

返回true。

在我的情况下,我在ASP.NET MVC Partial View中,如果属性不存在或者属性(boolean)为true,则想要渲染一些东西。

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

帮助了我。

编辑:现在,使用nameof运算符代替字符串化的属性名称可能很聪明。

答案 2 :(得分:2)

有两种可能性。

你真的没有Label财产。

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

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

编辑:

ooops,注意到您在GetProperty上致电typeof(MyClass)typeof(MyClass)Type,肯定没有Label属性。

答案 3 :(得分:1)

我收到了这个错误:" Type不包含GetProperty的定义"绑定接受的答案时。

这就是我最终的结果:

$('#jquery_jplayer_1').jPlayer({
                    ready: function () {
                        $(this).jPlayer('setMedia', {
                            mp3: '".$audio_link[$i]."'
                        });
                    },
                    play: function() { // To avoid multiple jPlayers playing together.
                        $(this).jPlayer('pauseOthers');
                        equal_height_pod();
                    },
                    swfPath: 'js',
                    supplied: 'mp3',
                    wmode: 'window',
                    globalVolume: true,
                    smoothPlayBar: true,
                    keyEnabled: true,
                    preload: 'none',
                    errorAlerts: true,
                    warningAlerts: true
                });
                $('#jquery_jplayer_1').bind($.jPlayer.event.play, function() {
                        $('.jp-audio').removeClass('showcontainer').parent('figure').parent('.leftImg').parent('li').removeClass('titlewrap');
                $('#jp_container_1').addClass('showcontainer').parent('figure').next('.introtitle').addClass('wrapintrotitle');
                        $('#jp_container_1').parent('figure').parent('.leftImg ').parent('li').addClass('titlewrap'); 
                });

答案 4 :(得分:0)

如果你像我一样有约束力:

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

答案 5 :(得分:0)

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

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

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