【问题标题】:Using "where" to limit template to non-bool struct types使用“where”将模板限制为非布尔结构类型
【发布时间】:2014-06-07 02:59:04
【问题描述】:

我正在编写一个对除 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 将模板限制为非布尔值,我认为我可以摆脱它。有没有办法做到这一点?或者是否有其他解决方案可以解决此限制?

【问题讨论】:

  • BinaryWriter.Write 确实有bool 的重载。关于你的问题,没有没有办法做到这一点。另请注意,C# 泛型与 C++ 模板完全不同,您不会针对您提供给 Write 调用的每种具体类型专门调用 Write
  • 您不能对T 施加任何约束,将其限制为“非布尔值”。 Here 是允许的约束列表。
  • 我会咬紧牙关,为Write 编写一个实现binWriter.Write 支持的每种类型的重载。最多 5 分钟,稍微复制和粘贴。

标签: c#


【解决方案1】:

您的代码没有按照您的想法执行。编译器试图将binWriter.Write 绑定到available overloads 之一。由于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
    }
}

但是使用泛型是没有意义的。

【讨论】:

    【解决方案2】:

    很遗憾,没有。

    您可以提供基类、接口或其他一些约束(查看http://msdn.microsoft.com/en-us/library/bb384067.aspx),但不能排除类型,尤其是原始类型。

    我建议改用一些转换机制(如果需要它们 - 根据@Lee 的评论,有一个重载)。

    【讨论】:

      猜你喜欢
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多