c# - 给定 Array.Cast<T>(),我如何通过反射确定 T?

标签 c# linq reflection

TL;DR - 我希望所有这些都能以相同的方式工作,但(根据评论)它们不会:

var c1 = new[] { FileMode.Append }.Cast<int>();
var c2 = new[] { FileMode.Append }.Select(x => (int)x);
var c3 = new[] { FileMode.Append }.Select(x => x).Cast<int>();

foreach (var x in c1 as IEnumerable)
  Console.WriteLine(x); // Append (I would expect 6 here!)

foreach (var x in c2 as IEnumerable)
  Console.WriteLine(x); // 6

foreach (var x in c3 as IEnumerable)
  Console.WriteLine(x); // 6

这是一个人为的例子;我显然不会将集合转换到 IEnumerable如果我不需要,在那种情况下,一切都会按预期进行。但我正在使用多种方法开发一个库,这些方法采用 object并返回一个序列化的字符串表示。如果它通过反射确定该对象实现了IEnumerable ,它会枚举它,并且在几乎所有情况下,返回预期的结果......除了这个奇怪的情况 Array.Cast<T> .

我可以在这里做两件事:

  1. 告诉使用物化 IEnumerable首先,例如 ToList() .
  2. 为每个采用 IEnumerable<T> 的受影响方法创建一个重载.

出于不同的原因,这些都不是理想的。是否有可能采用 object 的方法?以某种方式推断T什么时候Array.Cast<T>()通过了吗?

最佳答案

Is it possible for a method that takes an object to somehow infer T when Array.Cast() is passed?

不,不是在你给出的例子中。

您获得输出的原因是 Enumerable.Cast<T>() 方法进行了优化,允许在与您要求的类型兼容时返回原始对象:

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);
}

所以在你的第一种情况下,实际上什么都没有发生。 Cast<T>()方法只是返回你传递给方法的对象,所以当你取回它时,它已经经历了 Cast<T>() 的事实。完全丢失了。

你的问题没有任何其他细节说明你是如何陷入这种情况的,或者它在实际意义上为什么重要。但我们可以断定地说,鉴于您发布的代码,不可能实现您所说的目标。

关于c# - 给定 Array.Cast<T>(),我如何通过反射确定 T?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68504299/

相关文章:

c# - 为什么没有加载 Custom SecurityPermission?

c# - 列表框.SelectedItem

c# - 如何将 IQueryable<T> 转换为 Expression<Func<T, bool>>?

c# - 将方法作为参数传递

c# - XElement with LINQ 在特定节点后添加节点

C# 使用简单列表过滤对象列表

c# - 如何通过 COM 接口(interface)调用 C# 方法来传递函数指针

c# - ExecuteAsync RestSharp以允许backgroundWorker CancellationPending c#

c# - 访问回发时动态添加的控件

c# - 解析 HTTP JSON 响应 - C#