我想创建一个扩展方法,将long类型的ICollection转换为long类型的ICOllection。会是这样的:
public static void ConvetirLongANullableLong<T, U>(this ICollection<T> paramIcOrigenNoNullable, ICollection<U> paramIcDestinoNullable)
{
for (int i = 0; i < paramIcOrigenNoNullable.Count; i++)
{
paramIcDestinoNullable.Add((U)paramIcOrigenNoNullable.ElementAt(i));
}
}
但是我有一个问题,因为我无法将U转换为T。
这个想法是创建一个通用方法来转换例如长到长?在这种情况下,但是从int到int?或其他任何不可为空的基本类型。
是否有可能为每种类型创建一个方法?
这是由以下帖子所激发的:Fastest way to convert List<int> to List<int?>说,最好使用foreach而不使用linq select或linq cast,因为它比较慢。
谢谢。
PD:我给出V0ldek的答案,因为这是我在这篇文章中真正提出的要求,但是如果我使用linq select(至少在使用Entity Core 3.0时,PavelAnikhouski会如何在其中发表评论)的确更快。我不知道for选项是否在其他版本中更快,因为我指示的链接中的结果与PavelAnikhouski的情况和我自己的情况下的时间差别很大。
答案 0 :(得分:2)
如果您总是要从T
转换为T?
,那么就不需要类型U
。您知道U
,U = T?
。但是您确实需要约束T
进行构造。
public static void ConvertToCollectionOfNullable<T>(
this ICollection<T> source,
ICollection<T?> destination) where T : struct
{
for (int i = 0; i < source.Count; i++)
{
destination.Add(source.ElementAt(i));
}
}
此外,您可以在集合中使用foreach
以获得更干净的代码。
public static void ConvertToCollectionOfNullable<T>(
this ICollection<T> source,
ICollection<T?> destination) where T : struct
{
foreach (var element in source)
{
destination.Add(element);
}
}
答案 1 :(得分:1)
使用OfType<T>
中的Cast<T>
或System.Linq
方法,您可以变得更加简单
var list = new List<long>() { 1, 2, 3 };
var converted = list.OfType<long?>().ToList();
OfType<T>
不会抛出任何异常,如果强制转换会失败(例如Cast<T>
)
另一种选择是使用Select
方法。由于您知道结果类型,因此cast(编译器也可以帮助您)和装箱也不会有问题
var list = new List<long>() { 1, 2, 3 };
var converted = list.Select(_ => (long?)_).ToList();
答案 2 :(得分:1)
IEnumerable.Cast较慢,因为它使用拳击。这是发生了什么:
long? l = (long?)(object)8;
但这是将任何内容投射到任何内容的唯一方法。 如果您希望它更快地实现,请针对特定类型。
但是在特殊情况下,如果要将值类型转换为可空类型,则可以坚持使用泛型。您只需要避免处理两种类型(您的<T, U>
)是T和T ?,并且必须告诉编译器T是值类型:
public static IEnumerable<T?> Convert<T>(this IEnumerable<T> list) where T : struct
{
return list.Select(x => new T?(x));
}
如果希望更快,请避免使用LINQ枚举器(避免foreach)并使用简单的循环
public static IList<T?> Convert<T>(this IList<T> list) where T : struct
{
var newlist = new List<T?>(list.Count);
for (int i = 0; i < list.Count; i++)
newlist.Add(new T?(list[i]));
return newlist;
}