测试泛型方法参数是否为类
我有一个带有此签名的通用方法:
private void MyGenericMethod<T>(T arg) where T : class
{}
如果我向此方法传递一个整数,我会收到一个 ArgumentException ,表明传递的值与限制不匹配。这很棒,但是我如何预先确定我传递的内容将与“类”约束匹配,以便不引发异常?
I have a generic method with this signature:
private void MyGenericMethod<T>(T arg) where T : class
{}
If I pass, say, an integer to this method, I get an ArgumentException that the passed value does not match the restriction. This is great, but how can I predetermine that what I am passing will match the "class" constraint so that the exception is not thrown?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编译器已经为你做到了这一点 - 你实际上应该看到:
在编译时将其用作泛型类型或方法“blah.MyGenericMethod(T)”中的参数“T”。
棘手的场景是:
where T : class
很多 。有时最好对T
MakeGenericMethod
等) - 同样,只需在运行时检查另外,请注意
where T : class 实际上并不意味着
T
是一个类 - 它意味着它是一个引用类型,可以包含接口和委托。同样,where T : struct
实际上并不意味着T
是一个struct
- 它意味着它是一个不Nullable< 的结构;>
。The compiler will already do that for you - you should actually see:
at compile-time.
The tricky scenarios are:
where T : class
a lot. Sometimes it is better to use runtime validation againstT
MakeGenericMethod
, etc) - again, just check at runtimeAlso, note that
where T : class
doesn't actually meanT
is a class - it means it is a reference-type, which can include interfaces and delegates. Likewise,where T : struct
doesn't actually meanT
is astruct
- it means it is a struct that is notNullable<>
.您不能传递
int
,因为它是值类型,并且您已将您的方法限制为仅接受引用类型。如果您想支持其中任何一个,您需要删除泛型约束,如下所示
You can not pass
int
because it is a value type and you have constrained your Method to accept only reference type.if you want to support any of those you need to remove the generics constrain like following
如果传递的参数不是引用类型,您实际上会收到编译错误。但是,如果您对值类型进行装箱,则可以绕过该问题,但它是有效的引用类型。
如果您收到此错误是因为您在运行时执行了某些操作,例如使用反射来调用方法,或者您框定了值类型,那么您只需要在使用参数之前检查参数即可:
请注意,这将捕获所有值类型,无论它们是否盒装。另请注意,使用
is
还可以匹配其层次结构(基类/派生类)中的类型 true,而根据typeof
检查GetType
仅需要在该级别键入:显然在您的情况中,您不会想抛出
ArgumentException
,并且可能什么都不做。You actually get compilation errors if the argument being passed is not a reference type. If you box a value type, however, you can get around that, but then it's a valid reference type.
If you are getting this error because you do something at runtime, such as use reflection to call the method, or you box value types, then you will simply need to check the parameter before you use it:
Note that this will catch all value types, whether they are boxed or not. Also note that using
is
also matches true for the type in it's hierarchy (base / derived classes), whereas checkingGetType
againsttypeof
takes only the type at that level:Obviously in your case you won't want to throw an
ArgumentException
and perhaps just do nothing.