【发布时间】:2008-08-12 15:07:40
【问题描述】:
有没有办法强制/限制传递给原语的类型? (bool、int、string 等)
现在,我知道您可以通过 where 子句将泛型类型参数限制为类型或接口实现。但是,这不符合原语 (AFAIK) 的要求,因为它们并非都有共同点(除了 object 在有人说之前!:P)。
所以,我目前的想法是咬紧牙关,做一个大的 switch 语句并在失败时抛出 ArgumentException。
编辑 1:
澄清一下:
代码定义应该是这样的:
public class MyClass<GenericType> ....
和实例化:
MyClass<bool> = new MyClass<bool>(); // Legal
MyClass<string> = new MyClass<string>(); // Legal
MyClass<DataSet> = new MyClass<DataSet>(); // Illegal
MyClass<RobsFunkyHat> = new MyClass<RobsFunkyHat>(); // Illegal (but looks awesome!)
编辑 2
@Jon Limjap - 好点,我已经在考虑了。我确信有一个泛型方法可以用来确定该类型是值类型还是引用类型。
这对于立即删除许多我不想处理的对象很有用(但是您需要担心使用的结构,例如 Size )。有趣的问题不是吗? :)
这里是:
where T: struct
取自MSDN。
我很好奇。这可以使用扩展方法在 .NET 3.x 中完成吗?创建一个接口,并在扩展方法中实现该接口(这可能比有点胖的开关更干净)。另外,如果您以后需要扩展到任何轻量级自定义类型,它们也可以实现相同的接口,而无需更改基本代码。
你们觉得呢?
不幸的是我正在使用框架 2! :D
编辑 3
从Jon Limjaps Pointer 开始,这太简单了。太简单了,我几乎想哭,但它很棒,因为代码就像一个魅力!
这就是我所做的(你会笑的!):
添加到泛型类的代码
bool TypeValid()
{
// Get the TypeCode from the Primitive Type
TypeCode code = Type.GetTypeCode(typeof(PrimitiveDataType));
// All of the TypeCode Enumeration refer Primitive Types
// with the exception of Object and Empty (Null).
// Since I am willing to allow Null Types (at this time)
// all we need to check for is Object!
switch (code)
{
case TypeCode.Object:
return false;
default:
return true;
}
}
然后是一个小工具方法来检查类型并抛出异常,
private void EnforcePrimitiveType()
{
if (!TypeValid())
throw new InvalidOperationException(
"Unable to Instantiate SimpleMetadata based on the Generic Type of '" + typeof(PrimitiveDataType).Name +
"' - this Class is Designed to Work with Primitive Data Types Only.");
}
接下来需要做的就是在类构造函数中调用EnforcePrimitiveType()。任务完成! :-)
唯一的缺点是,它只会在运行时(显然)而不是设计时抛出异常。但这没什么大不了的,可以使用 FxCop 之类的实用程序(我们在工作中不使用)来获取。
在此特别感谢 Jon Limjap!
【问题讨论】:
-
您也可以在静态构造函数中调用检查,因此每个用作泛型参数的类型仅调用一次。
标签: c# generics primitive type-safety