gpt4 book ai didi

c# - 无法将 'System.Int32' 类型的对象转换为 'System.Int64' 类型

转载 作者:行者123 更新时间:2023-12-04 12:20:47 27 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Why does the Linq Cast<> helper not work with the implicit cast operator?

(3 个回答)


去年关闭。




如果错误无法转换类型为 System.Int64 的对象输入 System.Int32 ,我会理解这是由于数据缩小的可能性。但是,我不明白为什么会出现错误,无法转换 System.Int32 类型的对象输入 System.Int64 ,尽管范围是 long更高。

int[]             integers = { 1, 2, 3 };
IEnumerable<long> test1 = integers.OfType<long>();
IEnumerable<long> test2 = integers.Cast<long>();

foreach (var l in test2) ;

最佳答案

Cast 与 Convert 不同。 Int32 -> Int64是语义无损转换。许多 C# 类型使用 User-Definied Conversion Operator 重载“(type)”强制转换运算符并实际执行不允许类型转换的转换。

而 C# 语言会生成一个 Implicit Conversion为您提供常见且安全的代码模式,例如:

int num = 2147483647;
long bigNum = num;

但是这些是类型转换要求对象可分配给目标类型的变量的规则的异常(exception)。另一个异常(exception)是 object 类型的表达式。可以强制转换为任何类型,并且如果对象不可分配给该类型的变量,则会在运行时失败。
Enumerable.Cast<T>完全按照它说的做,并对集合中的每个元素执行 Cast。不是转换,即使类型实现了用户定义的转换运算符。这是因为类型转换来自 objectT ,从而绕过任何用户定义的转换运算符或 C# 隐式转换。
来源:
   public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source) 
{
IEnumerable<TResult> typedSource = source as IEnumerable<TResult>;
if (typedSource != null) return typedSource;
if (source == null) throw Error.ArgumentNull("source");
return CastIterator<TResult>(source);
}

static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source) {
foreach (object obj in source) yield return (TResult)obj;
}

Reference Source

请注意 Cast<T> 的参数是 Enumerable ,不是 Enumberable<TSource> .此 API 的目的是为非通用集合提供适配器。在 .NET 中引入泛型之前(注意它们不仅仅是一种语言功能), Enumerable是基本集合类型,要在 LINQ 中使用旧集合,必须将它们转换为 IEnumerable<T> .

即使此 API 的目标是应用用户定义的转换或隐式转换,在 C# 中也没有明显的方法来实现它。 C# 泛型不是模板*,泛型方法将有一个必须遵循 C# 规则的实现。 EG这样的事情;
public static IEnumerable<TDest> MyCast<TDest, TSource>(this IEnumerable<TSource> col)
{
foreach (var s in col)
yield return (TDest)s;
}

无法编译,因为编译器无法验证是否可从 TSource 类型的对象分配 TDest。因此,您必须将每个项目转换为 object首先,这正是采用非通用 IEnumerable 的版本中发生的情况。

你可以写类似的东西
yield return (TDest)Convert.ChangeType(s, typeof(TDest));

但是方法应该是:
public static class MyConvertExtension
{
public static IEnumerable<TDest> Convert<TDest, TSource>(this IEnumerable<TSource> col)
{
foreach (var s in col)
yield return (TDest)Convert.ChangeType(s, typeof(TDest));
}
}

* Differences Between C++ Templates and C# Generics

C++ allows code that might not be valid for all type parameters in the template, which is then checked for the specific type used as the type parameter. C# requires code in a class to be written in such a way that it will work with any type that satisfies the constraints. For example, in C++ it is possible to write a function that uses the arithmetic operators + and - on objects of the type parameter, which will produce an error at the time of instantiation of the template with a type that does not support these operators. C# disallows this; the only language constructs allowed are those that can be deduced from the constraints.

关于c# - 无法将 'System.Int32' 类型的对象转换为 'System.Int64' 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61417462/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com