C#: How to get all public (both get and set) string properties of a type

前端 未结 7 716
借酒劲吻你
借酒劲吻你 2020-12-02 14:21

I am trying to make a method that will go through a list of generic objects and replace all their properties of type string which is either null or

相关标签:
7条回答
  • 2020-12-02 14:36

    I suggest a different approach: AOP.
    You can intercept the setter and set the desired value to a valid one. With PostSharp it's quite easy.

    0 讨论(0)
  • 2020-12-02 14:41

    BindingFlags.Public | BindingFlags.Instance should do it

    GetSetMethod()

    0 讨论(0)
  • 2020-12-02 14:41

    I agree with other answers, but I prefer to refactor the search itself to be easly queried with Linq, so the query could be as follow:

            var asm = Assembly.GetExecutingAssembly();
            var properties = (from prop
                                  in asm.GetType()
                                    .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                              where 
                                prop.PropertyType == typeof (string) && 
                                prop.CanWrite && 
                                prop.CanRead
                              select prop).ToList();
            properties.ForEach(p => Debug.WriteLine(p.Name));
    

    I took for my example the Assembly type, which hasn't read/write string properties, but if the same code search for just read properties, the result will be:

    • CodeBase
    • EscapedCodeBase
    • FullName
    • Location
    • ImageRuntimeVersion

    Which are the string read-only Assembly type properties

    0 讨论(0)
  • 2020-12-02 14:42

    http://jefferytay.wordpress.com/2010/05/03/simple-and-useful-tostring/

    for a tostring override method which allows you to get all the properties of the class

    0 讨论(0)
  • 2020-12-02 14:45

    You will find the properties as such with BindingFlags.Public | BindingFlags.Instance. Then you will need to examine each PropertyInfo instance by checking the CanWrite and CanRead properties, in order to find out whether they are are readable and/or writeable.

    Update: code example

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

    I looked into it more in detail after your update. If you also examine the MethodInfo objects returned by GetGetMethod and GetSetMethod you will hit the target, I think;

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

    By default these two methods return only public getters and setters (risking a NullReferenceException in a case like this), but passing true as above makes them also return private ones. Then you can examine the IsPublic (or IsPrivate) properties.

    0 讨论(0)
  • 2020-12-02 14:49

    If you don't specify any binding flags you will get the public, instance properties -- which is what you want. But then you will need to check if the PropertyType on the PropertyInfo object is of type String. Unless you know in advance, you'll also need to check whether the property is readable/writable as @Fredrik indicates.

    using System.Linq;
    
    public static void ReplaceEmptyStrings<T>(List<T> list, string replacement)
    {
        var properties = typeof(T).GetProperties()
                                  .Where( p => p.PropertyType == typeof(string) );
        foreach(var p in properties)
        {
            foreach(var item in list)
            {
                if(string.IsNullOrEmpty((string) p.GetValue(item, null)))
                    p.SetValue(item, replacement, null);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题