是否可以从Object参数中排除IEnumerable和原始类型?

时间:2017-12-29 10:39:02

标签: c# generics

我有这种扩展方法:

public static T Foo<T>(this Object current) where T : class, new()
{
    ...
}

是否可以从&#34;这个对象当前&#34;?

中排除原始类型和IEnumerable接口

Editet 我的问题不是重复,因为在建议的问题中,问题是在重载方法之间的参数冲突。作者问,是否有可能从一种方法中排除String类型,以便为另一种方法选择它。这个问题的有用答案对我没有帮助

2 个答案:

答案 0 :(得分:7)

没有。你不能。没有可用于此类事物的泛型类型约束。一个选项可以是指定标记Obsolete的方法:

[Obsolete("Do not use with IEnumerable!", true)]
public static T Foo<T>(this IEnumerable current) where T : class, new()
{
    ...
}

你明白这个名单会变得无穷无尽。另一种选择是Roslyn代码分析器,它会检查您的代码是否存在不允许的组合,但这可能是过度的。

答案 1 :(得分:1)

Patrick Hofman已经给出正确答案,但我想提供另一种处理该问题的可能性

可能的方法

正如Evk已经在他的评论中说明的那样。

根据您要允许的类型数量,可以明确允许这些类型。

不良方法

我不喜欢在Genericmethods上添加过时的标签以强制执行某些类型的感觉。

  

警告:请勿使用以下方法!

可能不得检查类型并抛出异常。

/// <summary>
/// 
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="current">Dont throw in IENumerables !</param>
/// <returns></returns>
public static T Foo<T>(this Object current) where T : class, new() {
        if (current is IEnumerable) {
            throw new NotSupportedException($"Type  {current.GetType()} is not supported!");
        }
        //...
}

为什么这是一个糟糕的方法? - &gt;这可能会导致应用程序崩溃。

Patricks为什么接近更好? - &gt;他的方法导致编译器警告/错误,这比生产中的应用程序崩溃更好。