c#泛型约束哪里不是类?

时间:2011-09-26 06:44:16

标签: c# generics

是否存在一个通用的where子句,它确定T的类型是原始的?

 void Method<T>(T val) where T : primitive

情况下:

有一个用C语言编写的函数式语言,它以原始的非托管blitable类型为基础,或者可以很容易地推入基元的东西(例如,没有小时/分钟/秒的日期可以推送到int等)最初的计划是利用GPU。虽然不这样做。到目前为止,C#在其协调员角色中表现良好。我倾向于认为架构的家就像生活在C#中一样。这并不完全正确,但这个想法很好地为项目服务。

我喜欢OO,但是当谈到功能性想法时,我想将这些想法限制在该域中支持的类型中。有趣的是,我仍然依靠C#来帮助我保持结构化和纪律性。我没有看到改变。


还有其他原因可以让我更加详细地了解约束对我来说是件好事。

btw:resharper提出了我试过一段时间的显式接口。我真的很喜欢这种符号......而且约束也可以与界面一起使用。尼斯。然而,我遇到了Jon Skeet关于S / O关于这种混乱继承的警告。因此,回到更加劳动密集的运行时AssertIsXYZ。

为了更进一步,对我的限制是证明正确性的一步(旧观念,但仍然是好的观点)。打字系统似乎可以将其中的一部分推送到编译器。使用“where”这个词来考虑一个子句或短语(比如在SQL / LINQ中)。我不是要求它被带到n度。就我而言,编译器可以做得越多越好。

通过约束获得触觉帮助我澄清了一些想法。得到了信任......但遗憾的是我之后不得不评论约束。

8 个答案:

答案 0 :(得分:19)

我怀疑基于你对Jon的回答的评论,你想要的是一种将类型参数约束为 blittable types unmanaged types 的方法。

“非托管类型”是一种类型,其定义排除了对垃圾收集器跟踪的内存的任何引用;你只能用非托管类型制作指针类型。 Blittable类型是可以从托管代码编组到非托管代码而不对其位进行任何修改的那些类型;它们是非托管类型的子集。

许多人告诉我们,拥有一个将类型参数限制为非托管类型的通用约束会非常方便。我们已经尝试了具有此约束的C#和CLR原型,但目前还没有计划将该功能实际放入产品中。 如果您可以描述激发功能请求的方案,那么这将有助于我们针对数百种其他功能确定功能的优先级。

答案 1 :(得分:8)

where T : struct

与原始类型相同,请注意。它强制它成为不可为空的值类型。这将包括,例如,Guid(不是原始的)但排除Nullable<Guid>(也不是原始的,但不是一个类)

如果您可以更准确地了解您的要求,我们可以为您提供更多帮助。

答案 2 :(得分:7)

没有!原始类型没有约束。

执行原始类型的最佳选择如下:

void Method<T>(T val) where T:struct
{
    if (!typeof(T).IsPrimitive)
        throw new ArgumentException("Only primitive types are allowed.", "val");
}

OR

public void Method(int val)
{
    GenericMethod(val);
}

public void Method(double val)
{
    GenericMethod(val);
}

private void GenericMethod<T>(T val) where T:struct
{
}

答案 3 :(得分:2)

你不能这样做(至少目前)。如果您希望它是值类型:

void Method<T>(T val) where T : struct

或者你可以在运行时检查它以确保它真的很原始(我想你想要int / float / etc而不是所有的值类型?)

public static class Ext
{
    public static bool IsPrimitive(this Type t)
    {
        return t == typeof(int) || t == typeof(float) 
            || t == typeof(double) || ...
    }
}

编辑 LOL刚刚发现Type中有一个名为IsPrimitive的内置属性,这就是我要说的......

答案 4 :(得分:1)

不,C#不知道任何像primitive这样的关键字。

查看此帖子:How to define generic type limit to primitive types?

答案 5 :(得分:0)

没有,但您可以使用struct约束。

where T: struct

答案 6 :(得分:0)

约束必须是非密封类型,因此没有办法将泛型约束为基本类型。

答案 7 :(得分:0)

我只是在这个帖子中添加了一些新信息,抱歉挖掘它...

正如很多人已经回答的那样,以下结构可以用于这个原因很长一段时间了:

<div style="position: absolute; left: -256px; top: -256px; width: 256px; height: 256px;">
    <div style="position: absolute; left: 0px; top: 0px;">
         <img src="tile1.png" style="width: 256px; height: 256px;">
    </div>
</div>
<div style="position: absolute; left: 0px; top: -256px; width: 256px; height: 256px;">
    <div style="position: absolute; left: 0px; top: 0px;">
         <img src="tile2.png" style="width: 256px; height: 256px;">
    </div>
</div>
....

随着 C#7.3 的发布,人们可以写下:

void Method<T>(T val) where T : struct

来源: