繁体   English   中英

给定的 Array.Cast<T> (),如何通过反射确定T?

[英]Given Array.Cast<T>(), how do I determine T via 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. Tell 用于首先实现IEnumerable ,例如使用ToList()
  2. 为每个采用IEnumerable<T>受影响方法创建一个重载。

由于不同的原因,这两者都不是理想的。 Array.Cast<T>()时,接受object的方法是否有可能以某种方式推断T

当传递 Array.Cast() 时,接受对象的方法是否有可能以某种方式推断 T?

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

你得到你所做的输出的原因是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>()的事实完全丢失了。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM