Вы можете, но это будет, вероятно, рассматривал как текст, делая ищущий в этом столбце трудный и медленный. Вы лучше из использования связанной таблицы.
Примечание: этот ответ был правильным для C # 3, но в какой-то момент (C # 4? C # 5?) Вывод типа улучшился, так что метод IdentityFunction
, показанный ниже ] можно легко использовать
Нет, нет. Он должен быть общим, для начала:
public static Func<T, T> IdentityFunction<T>()
{
return x => x;
}
Но тогда вывод типа не будет работать, поэтому вам придется сделать:
SelectMany(Helpers.IdentityFunction<Foo>())
, что намного уродливее, чем x => x
.
Другая возможность состоит в том, что вы оберните это в метод расширения:
public static IEnumerable<T> Flatten<T>
(this IEnumerable<IEnumerable<T>> source)
{
return source.SelectMany(x => x);
}
К сожалению, с такой общей дисперсией, которая может не подходить для различных случаев в C # 3 ... это не будет применимо к Например, список
. Вы могли бы сделать его более общим: >
public static IEnumerable<TElement> Flatten<TElement, TWrapper>
(this IEnumerable<TWrapper> source) where TWrapper : IEnumerable<TElement>
{
return source.SelectMany(x => x);
}
Но опять же, у вас возникли проблемы с выводом типов, я подозреваю ...
EDIT: Чтобы ответить на комментарии ... да, C # 4 упрощает эту задачу. Или, скорее, это делает первый метод Flatten
более полезным, чем в C # 3. Вот пример, который работает в C # 4, но не работает в C # 3, потому что компилятор не может преобразовать из List
до >
IEnumerable
:
using System;
using System.Collections.Generic;
using System.Linq;
public static class Extensions
{
public static IEnumerable<T> Flatten<T>
(this IEnumerable<IEnumerable<T>> source)
{
return source.SelectMany(x => x);
}
}
class Test
{
static void Main()
{
List<List<string>> strings = new List<List<string>>
{
new List<string> { "x", "y", "z" },
new List<string> { "0", "1", "2" }
};
foreach (string x in strings.Flatten())
{
Console.WriteLine(x);
}
}
}
Does this work in the way you want? I realize Jon posted a version of this solution, but he has a second type parameter which is only necessary if the resulting sequence type is different from the source sequence type.
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source)
where T : IEnumerable<T>
{
return source.SelectMany(item => item);
}
Вы можете приблизиться к тому, что вам нужно. Вместо обычной статической функции рассмотрите метод расширения для вашего IEnumerable
, как если бы функция идентификации относится к коллекции, а не к типу (коллекция может генерировать функцию идентификации своих элементов):
public static Func<T, T> IdentityFunction<T>(this IEnumerable<T> enumerable)
{
return x => x;
}
с этим, вам не нужно снова указывать тип и писать:
IEnumerable<IEnumerable<T>> deepList = ... ;
var flat = deepList.SelectMany(deepList.IdentityFunction());
Это действительно немного оскорбительно, и я, вероятно, выбрал бы x => x
. Кроме того, вы не можете использовать его плавно (в цепочке), поэтому он не всегда будет полезен.