Property name as variable

喜你入骨 提交于 2019-12-25 02:16:46

问题


I need to find the biggest size of each string column in a database as one of the informations to design another database. The only access I have to the source database is by a web service. I can just do it for each of the many columns to find the biggest size but I want it generic so I can use it later.

I wrote this very simplified version to make it simple to understand. Two of the last lines have invented syntax and it is where I need help.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class myClass
    {
        private string s;
        public string S
        {
            get { return s; }
            set { s = value; }
        }
        private int i;
        public int I
        {
            get { return i; }
            set { i = value; }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Type myClassType = typeof(myClass);
            System.Reflection.PropertyInfo[] propertyInfo = myClassType.GetProperties();
            Dictionary<string, int> property = new Dictionary<string, int>();

            foreach (System.Reflection.PropertyInfo info in propertyInfo)
               if (info.PropertyType == typeof(System.String))
                    property.Add(info.Name, -1);

            myClass[] myPa = new myClass[2];
            myPa[0] = new myClass();
            myPa[0].S = "1";
            myPa[0].I = 0;
            myPa[1] = new myClass();
            myPa[1].S = "12";
            myPa[1].I = 1;

This is where I need help. I invented the c[pair.key]. How to have a reference to a property that I know the name of?

            foreach (myClass c in myPa)
                foreach (KeyValuePair<string, int> pair in property)
                    if (c[pair.Key].Length > pair.Value)
                        property[pair.Key] = c[pair.Key].Length;

            foreach (KeyValuePair<string, int> pair in property)
                Console.WriteLine("Property: {0}, Biggest Size: {1}", pair.Key, pair.Value);
        }
    }
}

Output shoud be:

Property: S Biggest Size: 2

回答1:


The following should suffice:

static void Main()
{
    // Demo data
    myClass[] myPa = new myClass[2];
    myPa[0] = new myClass();
    myPa[0].S = "1";
    myPa[0].I = 0;
    myPa[1] = new myClass();
    myPa[1].S = "12";
    myPa[1].I = 1;

    PrintMaxLengthsOfStringProperties(myPa);
}

public static void PrintMaxLengthsOfStringProperties<T>(IEnumerable<T> items)
{
    var t = typeof(T);
    t.GetProperties().Where(p => p.PropertyType == typeof(string)) // TODO: Add other filters
                        .SelectMany(p => items.Select(o => (string)p.GetValue(o, null)).Select(v => new { Property = p, Value = v }))
                        .GroupBy(u => u.Property)
                        .Select(gu => new { Property = gu.Key, MaxLength = gu.Max(u => u.Value != null ? u.Value.Length : 0) })
                        .ToList()
                        .ForEach(u2 => Console.WriteLine("Property: {0}, Biggest Size: {1}", u2.Property.Name, u2.MaxLength))
                        ;
}

Though you might add some extra filters on the "GetProperties" result set (such as taking out static ones, or indexing properties, etc.

It makes use of a couple of Linq extension functions, namely, "Where", "GroupBy", "SelectMany", "Select", and "Max" as well using anonymous types.




回答2:


Not very sure if I understood right, but:

What if just use indexed property in your class this[propertyname] which inside will return a value of specified property like an object.

    public class myClass
    {
        ....
        ....
        public object this[string propertyname]
        {
            get { /*use reflection to return property value, so Object*/ }

        }
        ....
        ....
    }

Which means, I'm afraid, you can not just write c[pair.key].Length, as Object does not have Length property. You need to cast it to desired type (string in your case) and only after use Length property.

If it's not what you were asking for, please refrase your question.



来源:https://stackoverflow.com/questions/7811586/property-name-as-variable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!