C# 泛型非约束,其中T:!数不清

C# 泛型非约束,其中T:!数不清,c#,.net,generics,ienumerable,C#,.net,Generics,Ienumerable,根据标题,是否可以在c#4中声明类型否定约束?否-在c#或CLR中都没有这样的概念。否,但是可以检查“是”,然后适当地处理它…您使用约束,以便确保您使用的类型具有某些属性/方法/。。。你想用 带有类型否定约束的泛型没有任何意义,因为没有必要知道缺少一些您不想使用的属性/方法。据我所知,这是不可能的 您可以执行一些运行时检查: public bool MyGenericMethod<T>() { // if (T is IEnumerable) // don't do this

根据标题,是否可以在c#4中声明类型否定约束?

否-在c#或CLR中都没有这样的概念。

否,但是可以检查“是”,然后适当地处理它…

您使用约束,以便确保您使用的类型具有某些属性/方法/。。。你想用


带有类型否定约束的泛型没有任何意义,因为没有必要知道缺少一些您不想使用的属性/方法。

据我所知,这是不可能的

您可以执行一些运行时检查:

public bool MyGenericMethod<T>()
{
    // if (T is IEnumerable) // don't do this

    if (typeof(T).GetInterface("IEnumerable") == null)
        return false;

    // ...

    return true;
}
public bool MyGenericMethod()
{
//如果(T是IEnumerable)//不要这样做
if(typeof(T).GetInterface(“IEnumerable”)==null)
返回false;
// ...
返回true;
}

此选项的一个用途是选项类型

public class Option<A,B> 
where A : !B
where B : !A
{
    private readonly A a;
    private readonly B b;

    private Option(){}

    public Option(A a) 
    {
        this.a = a
    }

    public Option(B b)  
    {
        this.b = b
    }
} 
公共类选项
哪里A:!B
B:!A.
{
私人只读A;
私有只读B;
私有选项(){}
公共选择(A)
{
这个a=a
}
公共选择(B)
{
这个.b=b
}
} 

运行时检查当然可以,但在编译时没有类型检查的好处

我发现自己正试图实施评论中提到的相同案例:

void doIt<T>(IEnumerable<T> what) { }
void doIt<T>(T whats) { }
void doIt(IEnumerable what){
void doIt(T whats){}
I以下代码除外,以引用第一种方法

doIt(new List<T>());
doIt(新列表());
但是它实际上引用了第二个

一种解决方案是像这样抛出论点:

doIt(new List<T>().AsEnumerable<T>());
doIt(newlist().AsEnumerable());
该强制转换可能被另一个重载隐藏:

void doIt<T>(List<T> whats) {
    doIt(whats.AsEnumerable<T>());
}
void doIt(列出内容){
doIt(what.AsEnumerable());
}

据我所知,不可能使用非合同。可以使用基类和/或接口来约束泛型。面对导致运行时失败的类似问题,我在泛型要处理的类上实现了一个接口:

public interface IOperations
{

}

public static T GenericOperationsFactory<T>(ILogger loggerInstance, ref ExecutionContext executionContext) 
        where T: IOperations
{
    var operationsContext = Factories.OperationsContextFactory(loggerInstance, ref executionContext);

    var operations = typeof(T).GetConstructor(new[] { typeof(OperationsContext) }).Invoke(new object[] { operationsContext });

    return (T)operations;
}

public abstract class OperationsBase:IOperations
{
    protected OperationsContext Context { get; set; }

    public OperationsBase(OperationsContext context)
    {
        Context = context;
    }
...

public class ListsOperations : OperationsBase
{
    public ListsOperations(OperationsContext context) :
        base(context)
    {

    }
公共接口操作
{
}
公共静态T GenericOperationsFactory(ILogger loggerInstance,ref ExecutionContext ExecutionContext)
其中T:IOperations
{
var-operationContext=Factories.operationContextFactory(loggerInstance,ref-executionContext);
var operations=typeof(T).GetConstructor(new[]{typeof(operationContext)}).Invoke(new object[]{operationContext});
返回(T)操作;
}
公共抽象类操作库:IOperations
{
受保护的OperationsContext上下文{get;set;}
公共OperationsBase(OperationsContext上下文)
{
上下文=上下文;
}
...
公共类列表操作:OperationsBase
{
公共列表操作(操作上下文上下文):
基础(上下文)
{
}
或者:

public static T GenericOperationsFactory<T>(ILogger loggerInstance, ref ExecutionContext executionContext) 
        where T: OperationsBase
{
    var operationsContext = Factories.OperationsContextFactory(loggerInstance, ref executionContext);

    var operations = typeof(T).GetConstructor(new[] { typeof(OperationsContext) }).Invoke(new object[] { operationsContext });

    return (T)operations;
}

public abstract class OperationsBase
{
    protected OperationsContext Context { get; set; }

    public OperationsBase(OperationsContext context)
    {
        Context = context;
    }
...

public class ListsOperations : OperationsBase
{
    public ListsOperations(OperationsContext context) :
        base(context)
    {

    }
公共静态T GenericOperationsFactory(ILogger loggerInstance,ref ExecutionContext ExecutionContext) 其中T:OperationsBase { var-operationContext=Factories.operationContextFactory(loggerInstance,ref-executionContext); var operations=typeof(T).GetConstructor(new[]{typeof(operationContext)}).Invoke(new object[]{operationContext}); 返回(T)操作; } 公共抽象类操作库 { 受保护的OperationsContext上下文{get;set;} 公共OperationsBase(OperationsContext上下文) { 上下文=上下文; } ... 公共类列表操作:OperationsBase { 公共列表操作(操作上下文上下文): 基础(上下文) { }
即使有,你能描述一个用例吗?观察到你有这样的需求是很奇怪的。你只能针对属于类家族的类型T进行编码。否则你怎么能用泛型编码呢?在这种情况下你不需要泛型,或者你需要修改你的用例。感兴趣的用例是允许以下重载共存
void doIt(T what){}
void doIt(IEnumerable whats){}
-目前存在歧义,因为第一个方法中的
T
可以是
IEnumerable
(因此我想指定
T
不应该是
IEnumerable
)…我提请您注意这样一个事实,即带有带T和T序列的方法的类型通常对这两个方法有不同的名称。例如,在列表中,Add和AddRange。这是有原因的。遵循这种模式。为什么投票结果接近?问题的答案可能是“否”,但这并不意味着问题没有价值。你不能像那样使用
is
,它测试对象是否与类型兼容。你的意思是
如果(typeof(t)==typeof(IEnumerable)){}
显然您没有收到错误:####无法同时实现“”和“”,因为它们可能会统一用于某些类型参数替换###…在某些情况下,当您希望指定genericstype2不能是generictype4I时,我可以通过使用一系列实现实例的抽象类来解决我的方案类似接口的ce,并继承抽象类..我想这就是Action等的工作方式..这个概念将来会变成C#和/或CLR吗?@RandRandom:我还没有听说过任何关于它的计划。请添加与该答案相对应的最新C#版本…以防将来发生变化…@Serge:我宁愿不这样做这一点。这将适用于网站上几乎所有基于语言的问题的答案,而且不可能每次有新版本的C#时都重新访问每个答案。@TravisReed:老实说,我认为这会给很多答案增加很多噪音。请注意,这个问题已经指定了C#的版本,人们应该查看发布日期对上下文的回答。