C#:如何获取类型的所有公共(获取和设置)字符串属性

Svi*_*ish 56 c# reflection

我试图创建一个方法,将通过一个通用对象列表,并替换所有类型的属性,或者替换stringnull空或者为空.

如何做到这一点的好方法?

我有这种...... shell ...到目前为止:

public static void ReplaceEmptyStrings<T>(List<T> list, string replacement)
{
    var properties = typeof(T).GetProperties( -- What BindingFlags? -- );

    foreach(var p in properties)
    {
        foreach(var item in list)
        {
            if(string.IsNullOrEmpty((string) p.GetValue(item, null)))
                p.SetValue(item, replacement, null);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

那么,我如何找到一个类型的所有属性:

  • 类型 string
  • 有公共的 get
  • 有公共的 set


我做了这个测试课程:

class TestSubject
{
    public string Public;
    private string Private;

    public string PublicPublic { get; set; }
    public string PublicPrivate { get; private set; }
    public string PrivatePublic { private get; set; }
    private string PrivatePrivate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

以下不起作用:

var properties = typeof(TestSubject)
        .GetProperties(BindingFlags.Instance|BindingFlags.Public)
        .Where(ø => ø.CanRead && ø.CanWrite)
        .Where(ø => ø.PropertyType == typeof(string));
Run Code Online (Sandbox Code Playgroud)

如果我打印出那些属性的名称,我得到了:

PublicPublic PublicPrivate PrivatePublic

换句话说,我得到两个属性太多了.


注意:这可能是以更好的方式完成的...使用嵌套的foreach和反射以及所有这里...但如果你有任何很好的替代想法,请让我知道因为我想学习!

Col*_*ett 93

你的代码被重写了.不使用LINQ也不使用var.

public static void ReplaceEmptyStrings<T>(List<T> list, string replacement)
{
    PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

    foreach (PropertyInfo p in properties)
    {
        // Only work with strings
        if (p.PropertyType != typeof(string)) { continue; }

        // If not writable then cannot null it; if not readable then cannot check it's value
        if (!p.CanWrite || !p.CanRead) { continue; }

        MethodInfo mget = p.GetGetMethod(false);
        MethodInfo mset = p.GetSetMethod(false);

        // Get and set methods have to be public
        if (mget == null) { continue; }
        if (mset == null) { continue; }

        foreach (T item in list)
        {
            if (string.IsNullOrEmpty((string)p.GetValue(item, null)))
            {
                p.SetValue(item, replacement, null);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Fre*_*örk 9

你会发现这样的属性BindingFlags.Public | BindingFlags.Instance.然后,您需要通过检查CanWrite和CanRead属性来检查每个PropertyInfo实例,以便确定它们是否可读和/或可写.

更新:代码示例

PropertyInfo[] props = yourClassInstance.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < props.Length; i++)
{
    if (props[i].PropertyType == typeof(string) && props[i].CanWrite)
    {
        // do your update
    }
}
Run Code Online (Sandbox Code Playgroud)

更新后我更详细地研究了它.如果您还检查GetGetMethod和GetSetMethod返回的MethodInfo对象,我会想到你会击中目标;

 var properties = typeof(TestSubject).GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Where(ø => ø.CanRead && ø.CanWrite)
        .Where(ø => ø.PropertyType == typeof(string))
        .Where(ø => ø.GetGetMethod(true).IsPublic)
        .Where(ø => ø.GetSetMethod(true).IsPublic);
Run Code Online (Sandbox Code Playgroud)

默认情况下,这两个方法只返回公共getter和setter(在这种情况下冒着NullReferenceException),但是true如上所述传递它们也会返回私有的.然后,您可以检查IsPublic(或IsPrivate)属性.