根据标题,是否可以在c#4中声明类型否定约束?
答案 0 :(得分:41)
不 - 在C#或CLR中都没有这样的概念。
答案 1 :(得分:4)
据我所知,不可能这样做。
您可以做的是进行一些运行时检查:
public bool MyGenericMethod<T>()
{
// if (T is IEnumerable) // don't do this
if (typeof(T).GetInterface("IEnumerable") == null)
return false;
// ...
return true;
}
答案 2 :(得分:3)
我发现自己试图实施评论中提到的相同案例:
void doIt<T>(IEnumerable<T> what) { }
void doIt<T>(T whats) { }
我例外以下代码引用第一种方法:
doIt(new List<T>());
但实际上引用第二个。
一种解决方案是强制转换这样的论点:
doIt(new List<T>().AsEnumerable<T>());
施法者可能被另一次重载隐藏:
void doIt<T>(List<T> whats) {
doIt(whats.AsEnumerable<T>());
}
答案 3 :(得分:0)
不,但是可以用“是”来检查,然后适当地处理它......
答案 4 :(得分:0)
您使用约束,以便确保您使用的类型具有一些属性/方法/ ... 您想要使用。
具有类型否定约束的泛型没有任何意义,因为没有任何目的可以知道某些属性/方法您不想使用。
答案 5 :(得分:0)
一个用途就是选项类型。
Uncaught TypeError: d3.hexbin is not a function
运行时检查当然可行,但在编译时你不会有类型检查的好处。
答案 6 :(得分:-1)
据我所知,没有约束是不可能的。您可以使用基类和/或接口来约束泛型。面对导致运行时失败的类似问题,我在Generic要处理的类上实现了一个接口:
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)
{
}
或者:
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)
{
}