Некоторые мои лучшие расширения метода (у меня есть много!):
public static T ToEnum<T>(this string str) where T : struct
{
return (T)Enum.Parse(typeof(T), str);
}
//DayOfWeek sunday = "Sunday".ToEnum<DayOfWeek>();
public static string ToString<T>(this IEnumerable<T> collection, string separator)
{
return ToString(collection, t => t.ToString(), separator);
}
public static string ToString<T>(this IEnumerable<T> collection, Func<T, string> stringElement, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (var item in collection)
{
sb.Append(stringElement(item));
sb.Append(separator);
}
return sb.ToString(0, Math.Max(0, sb.Length - separator.Length)); // quita el ultimo separador
}
//new []{1,2,3}.ToString(i=>i*2, ", ") --> "2, 4, 6"
кроме того, следующие предназначены, чтобы быть в состоянии продолжиться в той же строке почти в любой ситуации, не объявляя новые переменные и затем удаляя состояние:
public static R Map<T, R>(this T t, Func<T, R> func)
{
return func(t);
}
ExpensiveFindWally().Map(wally=>wally.FirstName + " " + wally.LastName)
public static R TryCC<T, R>(this T t, Func<T, R> func)
where T : class
where R : class
{
if (t == null) return null;
return func(t);
}
public static R? TryCS<T, R>(this T t, Func<T, R> func)
where T : class
where R : struct
{
if (t == null) return null;
return func(t);
}
public static R? TryCS<T, R>(this T t, Func<T, R?> func)
where T : class
where R : struct
{
if (t == null) return null;
return func(t);
}
public static R TrySC<T, R>(this T? t, Func<T, R> func)
where T : struct
where R : class
{
if (t == null) return null;
return func(t.Value);
}
public static R? TrySS<T, R>(this T? t, Func<T, R> func)
where T : struct
where R : struct
{
if (t == null) return null;
return func(t.Value);
}
public static R? TrySS<T, R>(this T? t, Func<T, R?> func)
where T : struct
where R : struct
{
if (t == null) return null;
return func(t.Value);
}
//int? bossNameLength = Departament.Boss.TryCC(b=>b.Name).TryCS(s=>s.Length);
public static T ThrowIfNullS<T>(this T? t, string mensaje)
where T : struct
{
if (t == null)
throw new NullReferenceException(mensaje);
return t.Value;
}
public static T ThrowIfNullC<T>(this T t, string mensaje)
where T : class
{
if (t == null)
throw new NullReferenceException(mensaje);
return t;
}
public static T Do<T>(this T t, Action<T> action)
{
action(t);
return t;
}
//Button b = new Button{Content = "Click"}.Do(b=>Canvas.SetColumn(b,2));
public static T TryDo<T>(this T t, Action<T> action) where T : class
{
if (t != null)
action(t);
return t;
}
public static T? TryDoS<T>(this T? t, Action<T> action) where T : struct
{
if (t != null)
action(t.Value);
return t;
}
Hope это не похоже на прибытие из Марса:)
Если ваш тип коллекции реализует IList
(чтобы иметь возможность Add ()
к нему), вы можете написать метод расширения:
public static Extensions
{
public static TColl ToTypedCollection<TColl, T>(this IEnumerable ien)
where TColl : IList<T>, new()
{
TColl collection = new TColl();
foreach (var item in ien)
{
collection.Add((T) item);
}
return collection;
}
}
Нет, нет. Когда вы используете операторы запроса, они не используют экземпляры исходной коллекции для создания перечисления. Скорее, он использует частные реализации (возможно, анонимные, а возможно, и нет) для обеспечения этой функциональности.
Если вы хотите, чтобы это было в вашей исходной коллекции, у вас должен быть конструктор типа, который принимает IEnumerable
(или все, что хранится в вашей коллекции, если это определенно), а затем передать запрос конструктору.
Затем вы можете использовать это для создания метода расширения для IEnumerable
с именем В
, который примет IEnumerable
, а затем передаст его конструктору вашего типа и вернет его.
Нет. Вы можете следовать шаблону, установленному методами расширения ToList и ToDictionary - написать аналогичный метод расширения для загрузки собственного типа коллекции из IEnumerable.
Вы можете написать свой собственный экземпляр IComparer, чтобы иметь возможность сортировать ваш собственный сбор.
Грубая сила: вы можете пройти через IEnumerable и сбросить каждый элемент обратно в новый экземпляр вашего пользовательского сборник.
Вы можете инициализировать список с помощью IEnumerable:
Если items имеет тип IEnumerable, вы можете создать такой список:
var list = new List<string>(items);
или просто вызвать items.ToList () :
var list = items.ToList();
Какие интерфейсы реализует ваша настраиваемая коллекция?
Если это IList, вы могли бы использовать .ToList () в IEnumerable. Если это IDictionary, вы сможете использовать .ToDictionary () в IEnumerable И т. Д.
, чтобы сделать из него что-то более подходящее для вас.
Вы можете написать метод расширения для IEnumerable для .ToMyCollection (), если нет ничего похожего.
Перечислимые объекты и коллекции - довольно разные звери.
Перечисления позволяют, ну, перечислять, в то время как коллекции имеют основанные на индексе средства доступа, свойство Count и тому подобное. Чтобы создать коллекцию, вам действительно нужно будет перечислить IEnumerable. Типичные коллекции, такие как List
Если вы посмотрите в класс System.Linq.Enumerable, есть несколько методов расширения, которые позволят вам преобразовать ваш тип IEnumerable либо в массив, либо в ToList
var myEnumerable = this.GetEnumerator();
var array = myEnumerable.ToArray();
var list myEnumerable.ToList();
. Вы можете следовать этому подходу. и создайте собственный метод расширения, который будет преобразован в вашу пользовательскую коллекцию
public static CustomCollection<TSource> ToCustomCollection<TSource>(this IEnumerable<TSource> source);
Вам действительно нужен собственный тип коллекции? Похоже, все, что вы хотите с этим сделать, обеспечивается существующими типами общих коллекций, и, возможно, вам просто нужно добавить метод расширения или для них.
LINQ хорош, потому что он рассматривает исходные коллекции, как этот, как неизменяемые - он не изменяет их. Использование методов расширения просто перечисляет их в указанном вами альтернативном порядке - вы не создаете НОВЫЙ настраиваемый список таким образом.
Я бы предложил два варианта: