Объединить <T>(список <T>список, строка, указаннаяPropertyOfT)? - PullRequest
0 голосов
/ 27 октября 2011

От параметра к свойству?

public class ConcatenateListTMember
{
    public static void Test()
    {
        var someList = new List<AnyClass>();
        someList.Add(new AnyClass("value1"));
        someList.Add(new AnyClass("value2"));
        Console.WriteLine(Concatenate(someList, "SomeProperty"));
        Console.ReadLine();
    }

    static string Concatenate<T>(List<T> list, string specifiedPropertyOfT)
    {
        string output = String.Empty;
        // TODO: Somehow concatenate all the specified property elements in the list?
        return output;
    }
}

internal class AnyClass
{
    public AnyClass(string someProperty)
    {
        SomeProperty = someProperty;
    }

    public string SomeProperty { get; set; }
}

Как можно реализовать универсальный метод в этом примере кода?

  • Обратите внимание, что specifiedPropertyOfT не имеетбыть строкой, если та же цель может быть достигнута с использованием другого типа.
  • В идеале отражение не требуется:)

Ответы [ 3 ]

5 голосов
/ 27 октября 2011

Я думаю, вы ищете новые перегрузки string.Join в .NET 4, которые позволили бы:

IEnumerable<AnyClass> sequence = ...;
string joined = string.Join(",", sequence.Select(x => x.SomeProperty));

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

Обратите внимание, что селектор в Select не должен возвращать строки - String.Join вызовет ToString для любых нестроковых значений.

1 голос
/ 27 октября 2011

Попробуйте что-нибудь подобное. Я создал метод расширения в IEnumerable:

public static class Extension
{
    public static string ConcatinateString<T>(this IEnumerable<T> collection, Func<T, string> GetValue)
    {
        StringBuilder sb = new StringBuilder();
        foreach (var item in collection)
        {
            sb.Append(GetValue(item));
        }
        return sb.ToString();
    }
}

Тогда так назовите это, вы бы использовали что-то вроде этого:

var values = new List<TestClass>
        {
            new TestClass(){Name="John",Comment="Hello"},
            new TestClass(){Name="Smith", Comment="Word"}
        };
string s = values.ConcatinateString((x => x.Name));
string v = values.ConcatinateString((x => x.Comment));

В этом примере s = "JohnSmith" и v = "HelloWord". Func () дает вам гибкость. Вы в основном указываете функции, куда идти, чтобы получить строку для конкатенации. Я также использовал StringBuilder на случай, если вы работаете с длинными коллекциями.

1 голос
/ 27 октября 2011

Еще лучше - метод расширения:

static string Concatenate<T>(this IEnumerable<T> list, Func<T,string> func)
{
    return String.Join("",list.Select(func));
}

Использование:

someList.Concatenate(i => i.SomeProperty);

Живой пример: http://rextester.com/runcode?code=LRA78268

...