使用"where"限制模板只适用于非布尔结构类型

3

我正在编写一个通用的模板,适用于除 bool 以外的所有基本类型。具体来说,它将向不支持 Write(bool) 的 BinaryWriter 写入。

public void Write<T>(T val) where T : struct
{
    if (binWriter != null)
    {
        binWriter.Write(val);
    }
}

C#编译器给我错误提示:
error CS1502: The best overloaded method match for 'System.IO.BinaryWriter.Write(bool)' has some invalid arguments

我假设,如果我可以使用“where”将模板限制在非布尔值上,那么我就可以摆脱它。有没有办法做到这一点?或者有没有其他的解决方案来解决这个限制?

1
BinaryWriter.Write确实有一个bool的重载。关于你的问题,不,没有办法做到这一点。此外,请注意C#泛型与C++模板非常不同,你不会得到对Write的调用针对你提供给Write的每个具体类型进行专门化的情况。 - Lee
你无法对 T 设置任何限制,以限制它只能是“不是布尔值的东西”。这里是允许的约束条件列表。 - RB.
1
我会咬紧牙关,为 Write 写一个重载函数,实现 binWriter.Write 支持的每种类型。只需花费不到5分钟,稍微复制粘贴一下即可。 - Scott Chamberlain
2个回答

4
你的代码并不像你想象的那样运行。编译器试图将binWriter.Write绑定到可用重载之一。由于object是类型限制中唯一的共同基类,并且不存在接受object参数的重载,因此编译器无法绑定到重载并选择一个(我猜是按字母顺序第一个)在错误消息中显示给你。
你可以使用dynamic而不是泛型,在运行时进行绑定。
public void Write(dynamic val) 
{
    if (binWriter != null)
    {
        binWriter.Write(val);
    }
}

如果您尝试使用没有适当重载的类型,它将在运行时失败。

另一种选择是确定类型并绑定到适当的重载函数:

public void Write<T>(T val) where T : struct
{
    if (binWriter != null)
    {
        if(typeof(T) == typeof(bool)
            binWriter.Write((bool)val);
        else if(typeof(T) == typeof(byte)
            binWriter.Write((byte)val);

        ..etc
    }
}

但是使用泛型就没有意义了。

0

很遗憾,不行。

您可以提供一个基类、接口或其他约束条件(请参阅http://msdn.microsoft.com/en-us/library/bb384067.aspx),但您无法排除特定类型,尤其是原始类型。

我建议改用一些转换机制(如果需要的话-根据 @Lee 的评论,已经有重载实现了)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接