Имя свойства как переменная - PullRequest
0 голосов
/ 18 октября 2011

Мне нужно найти самый большой размер каждого строкового столбца в базе данных в качестве одной из сведений для проектирования другой базы данных.Единственный доступ к исходной базе данных у меня есть через веб-сервис.Я могу просто сделать это для каждого из множества столбцов, чтобы найти самый большой размер, но я хочу, чтобы он был общим, чтобы я мог использовать его позже.

Я написал эту очень упрощенную версию, чтобы ее было легко понять.В двух из последних строк был изобретен синтаксис, и именно здесь мне нужна помощь.

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;

Здесь мне нужна помощь.Я изобрел c[pair.key].Как получить ссылку на свойство, имя которого я знаю?

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

Вывод должен быть:

Property: S Biggest Size: 2

Ответы [ 2 ]

2 голосов
/ 18 октября 2011

Должно быть достаточно:

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

Хотя вы можете добавить некоторые дополнительные фильтры в набор результатов "GetProperties" (например, удалить статические или индексировать свойства и т. Д.)

Он использует несколько функций расширения Linq, а именно: «Где», «GroupBy», «SelectMany», «Select» и «Max», а также использует анонимные типы.

0 голосов
/ 18 октября 2011

Не совсем уверен, правильно ли я понял, но:

Что если просто использовать индексированное свойство в вашем классе, это [propertyname], которое внутри будет возвращать значение указанного свойства как объект.

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

        }
        ....
        ....
    }

Что означает, я боюсь, вы не можете просто написать c[pair.key].Length, так как Object не имеет Length свойства.Вам нужно привести его к нужному типу (string в вашем случае) и только после использования свойства Length.

Если это не то, о чем вы просили, пожалуйста, перефразируйте ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...