创建一个扩展方法以将类型包装为IEnumerables(Creating an extension method to wrap types as IEnumerables)

编程入门 行业动态 更新时间:2024-10-18 10:15:20
创建一个扩展方法以将类型包装为IEnumerables(Creating an extension method to wrap types as IEnumerables)

我想创建一个有效地将单个对象包装为IEnumerables的扩展方法。 这是为了避免最终在表达式中间放置一个new [] {}的情况。 这很容易使用以下方法:

public static IEnumerable<TSource> WrapAsEnumerable<TSource>(this TSource source) { return new[] { source }; }

问题是这将应用于任何和所有类型(这是预期的行为),但这也会产生使IEnumerable <T>实例上的方法可用的副作用。 在已解析的扩展类型是IEnumerable<T> ,我只想返回此IEnumerable,因为备选方案发现自己有一个IEnumerable<IEnumerable<T>> ,这不是你真正想到的。调用方法。

本能地(也许是睡意),我首先创建了一个看起来像这样的重载

public static IEnumerable<TSource> WrapAsEnumerable<TSource>(this IEnumerable<TSource> source) { return source; }

为了处理要包装的类型是IEnumerable<T> ,但是当然,控制流总是解析为第一种方法。

所以,问题是:我怎样才能创建这样一个包装方法来处理扩展参数实例是IEnumerable<T>和不处理的情况?

I wanted to create an extension method that would efficiently wrap single objects as IEnumerables. This was to avoid the cases where you end up putting a new [] {} in the middle of an expression. This is easy enough to do using the following method:

public static IEnumerable<TSource> WrapAsEnumerable<TSource>(this TSource source) { return new[] { source }; }

The problem is that this will be applied to any and all types (which is the expected behavior), but this will also have the side effect of making the method available on IEnumerable <T> instances. In the case where the resolved extended type is an IEnumerable<T>, I would simply like to return this IEnumerable, since the aternative is finding myself with a IEnumerable<IEnumerable<T>>, which is not really what you'd expect when calling the method.

Instinctively (and perhaps sleepily), I first created an overload that looked like this

public static IEnumerable<TSource> WrapAsEnumerable<TSource>(this IEnumerable<TSource> source) { return source; }

in order to handle the case where the type to wrap is an IEnumerable<T>, But of course, the control flow always resolves to the first method.

So, the question is: how could I create such a wrapping method that handles both the case where the extended parameter instance is an IEnumerable<T> and when it is not ?

最满意答案

这是另一个尝试,灵感来自Eric Lippert的优秀帖子: https : //stackoverflow.com/a/1451184/4955425 。

您可以通过将2个扩展方法放在命名空间层次结构中的不同级别来控制重载决策。

namespace MyExtensions { public static class HighPrecendenceExtensions { public static IEnumerable<TSource> WrapAsEnumerable<TSource>(this IEnumerable<TSource> source) { return source; } } namespace LowerPrecedenceNamespace { public static class LowPrecedenceExtensions { public static IEnumerable<TSource> WrapAsEnumerable<TSource>(this TSource source) { return new[] { source }; } } } }

但是,缺点是你总是需要引用两个命名空间来获得正确的方法调用行为。

using MyExtensions; using MyExtensions.LowerPrecedenceNamespace;

Here is another attempt, inspired from Eric Lippert's excellent post at: https://stackoverflow.com/a/1451184/4955425.

You can control the overloading resolution by placing your 2 extension methods at different levels in the namespace hierarchy.

namespace MyExtensions { public static class HighPrecendenceExtensions { public static IEnumerable<TSource> WrapAsEnumerable<TSource>(this IEnumerable<TSource> source) { return source; } } namespace LowerPrecedenceNamespace { public static class LowPrecedenceExtensions { public static IEnumerable<TSource> WrapAsEnumerable<TSource>(this TSource source) { return new[] { source }; } } } }

However, the downside is that you'll always need to refer to both namespaces to get the right method invocation behavior.

using MyExtensions; using MyExtensions.LowerPrecedenceNamespace;

更多推荐

本文发布于:2023-08-02 18:54:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1379610.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:创建一个   类型   方法   IEnumerables   Creating

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!