“未找到属性设置方法”反射时出错

发布于 2025-01-07 12:39:10 字数 875 浏览 0 评论 0原文

我试图反映一些类属性并以编程方式设置它们,但看起来我的 PropertyInfo 过滤器之一不起作用:

//Get all public or private non-static properties declared in this class (no inherited properties) - that have a getter and setter.
PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.SetProperty );

我收到一条错误消息,

pi.SetValue(this, valueFromData, null);

因为该属性只有一个 get{} 方法,没有 set{} 方法。

我的问题是,为什么这个属性没有从 props 中过滤掉?我认为这就是 BindingFlags.SetProperty 的目的。

未过滤掉的属性是:

    public String CollTypeDescription
    {
        get { return _CollTypeDescription; }
    }

请注意,我想过滤无法提前工作的属性,因为我一次列出了所有属性。我不想在事后使用 pi.GetSetMethod() 来确定是否可以使用设置器。

I'm trying to reflect over some class properties and set them programmatically, but it looks like one of my PropertyInfo filters isn't working:

//Get all public or private non-static properties declared in this class (no inherited properties) - that have a getter and setter.
PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.SetProperty );

I'm getting an error on the line

pi.SetValue(this, valueFromData, null);

Because the property has only a get{} method, no set{} method.

My question is, why wasn't this property filtered out of props? I thought that was the purpose of BindingFlags.SetProperty.

The property not getting filtered out is:

    public String CollTypeDescription
    {
        get { return _CollTypeDescription; }
    }

Note that I want to filter properties that won't work ahead of time because I'm listing them all at once. I don't want to use pi.GetSetMethod() after the fact to determine whether I can use the setter.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

铁轨上的流浪者 2025-01-14 12:39:10

从文档中:

BindingFlags.SetProperty

指定应设置指定属性的值。为了
COM 属性,指定此绑定标志相当于
指定 PutDispProperty 和 PutRefDispProperty。

BindingFlags.SetPropertyBindingFlags.GetProperty 分别过滤缺少 setter 或 getter 的属性。

要检查是否可以设置属性,请使用 CanWrite 属性。

if (pi.CanWrite)
    pi.SetValue(this, valueFromData, null);

From the documentation:

BindingFlags.SetProperty

Specifies that the value of the specified property should be set. For
COM properties, specifying this binding flag is equivalent to
specifying PutDispProperty and PutRefDispProperty.

BindingFlags.SetProperty and BindingFlags.GetProperty do not filter properties that are missing setters or getters, respectively.

To check if a property can be set, use the CanWrite property.

if (pi.CanWrite)
    pi.SetValue(this, valueFromData, null);
森林散布 2025-01-14 12:39:10

感谢肯提供信息。这看起来是最好的解决方案,我可以通过在 LINQ 过滤器中测试 GetSetMethod(true) 来过滤掉它们:

// Get all public or private non-static properties declared in this class
// (e.g. excluding inherited properties) that have a getter and setter.
PropertyInfo[] props = this.GetType()
    .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance |
                   BindingFlags.Public | BindingFlags.NonPublic)
    .Where(p => p.GetGetMethod(true) != null && p.GetSetMethod(true) != null)
    .ToArray();

或者,使用 CanReadCanWrite

PropertyInfo[] props = this.GetType()
    .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance |
                   BindingFlags.Public | BindingFlags.NonPublic)
    .Where(p => p.CanRead && p.CanWrite)
    .ToArray();

我不清楚对于 get/set 方法的不同保护级别,这些不同的方法是否会产生不同的结果。

Thanks to ken for the information. It looks like the best solution I can get it to filter them out by testing GetSetMethod(true) in a LINQ filter:

// Get all public or private non-static properties declared in this class
// (e.g. excluding inherited properties) that have a getter and setter.
PropertyInfo[] props = this.GetType()
    .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance |
                   BindingFlags.Public | BindingFlags.NonPublic)
    .Where(p => p.GetGetMethod(true) != null && p.GetSetMethod(true) != null)
    .ToArray();

Alternatively, using CanRead and CanWrite:

PropertyInfo[] props = this.GetType()
    .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance |
                   BindingFlags.Public | BindingFlags.NonPublic)
    .Where(p => p.CanRead && p.CanWrite)
    .ToArray();

It's unclear to me whether these different approaches will yield different results for different protection levels of the get/set methods.

许你一世情深 2025-01-14 12:39:10

我使用这段代码:

    public class CustomBinder
{
    public static void BindModel(object myClass)
    {
        var stringItems = myClass?.GetType()
            .GetProperties()
            .Where(x => x.PropertyType == typeof(string)).ToList();

        if (!(stringItems?.Count > 0)) return;

        foreach (var propertyInfo in stringItems)
        {
            if (propertyInfo.GetValue(myClass, null) != null)
            {
                var val = propertyInfo.GetValue(myClass).ToString().Replace(...);
           if(propertyInfo.CanWrite)
                propertyInfo.SetValue(myClass, val);
            }

        }

    }
    public static void BindModel(List<string> listString)
    {
        if (!(listString?.Count > 0 )) return;

        for (var i = 0; i < listString.Count; i++)
            listString[i] = listString[i].Replace(...);

    }

}

I use this code:

    public class CustomBinder
{
    public static void BindModel(object myClass)
    {
        var stringItems = myClass?.GetType()
            .GetProperties()
            .Where(x => x.PropertyType == typeof(string)).ToList();

        if (!(stringItems?.Count > 0)) return;

        foreach (var propertyInfo in stringItems)
        {
            if (propertyInfo.GetValue(myClass, null) != null)
            {
                var val = propertyInfo.GetValue(myClass).ToString().Replace(...);
           if(propertyInfo.CanWrite)
                propertyInfo.SetValue(myClass, val);
            }

        }

    }
    public static void BindModel(List<string> listString)
    {
        if (!(listString?.Count > 0 )) return;

        for (var i = 0; i < listString.Count; i++)
            listString[i] = listString[i].Replace(...);

    }

}
梦在深巷 2025-01-14 12:39:10

我了解 GetProperties() 方法,以便它返回具有 BindingFlags.GetProperty BindingFlags.SetProperty 的每个属性。
因此,如果您只需要具有设置器的属性,则必须删除 BindingFlags.GetProperty 标志。但我没有测试过,所以我可能是错的。

我的答案是-1。所以看来我的回答是错误的。

I understand the GetProperties() method so that it returns every property that has BindingFlags.GetProperty or BindingFlags.SetProperty.
So if you want only properties that have setters you must remove the BindingFlags.GetProperty flag. But I did not tested it so I can be wrong.

My answer got a -1. So it seems that my answer is wrong.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文