基元类型的运算符重载

本文关键字:运算符 重载 类型 | 更新日期: 2023-09-27 18:34:41

我使用一个类作为包装器来保存一组代表不同选项或特征的几个无符号短裤。每个短音都初始化为2的幂,因此我可以轻松地将它们相加或或在一起。

public static class Options
{
    public static readonly ushort OPTN0 = 1 << 0; // 0001
    public static readonly ushort OPTN1 = 1 << 1; // 0010
    public static readonly ushort OPTN2 = 1 << 2; // 0100
    ...
}

public static void main(string[] args)
{
    funcThatUsesOptns(Option.OPTN0); // works fine
    funcThatUsesOptns(Option.OPTN1 | Option.OPTN2); // fails because '|' returns int
    funcThatUsesOptns((ushort)(Option.OPTN0 | Option.OPTN2)); // works fine
    ...
}

但是,由于"+"和"|"在这种情况下都返回整数,因此我每次都必须强制转换它们。例如,a 和 b 都初始化为 int:

var a = Option.OPTN0 + Option.OPTN1;
var b = Option.OPTN0 | Option.OPTN1;

所以我想知道基元类型是否可以使用运算符重载。如果没有,有没有更好的方法来实现这一目标?当然,每次都投掷它不会杀死我,但我希望有一种更干净的方式。

编辑:我实际上正在使用它来渲染许多简单的几何对象(立方体,金字塔,...(。我希望能够快速告诉渲染器要绘制哪些面。如果一个物体上的人脸接触另一个物体或背对着相机,我可以设置相应的位来告诉渲染器不要绘制该面。

基元类型的运算符重载

似乎您真正想要的是基于 ushort 的枚举值,如下所示:

[Flags]
public enum Options : ushort
{
     OPTN0 = 1 << 0, // 0001
     OPTN1 = 1 << 1, // 0010
     OPTN2 = 1 << 2, // 0100    
}

然后,您可以使用枚举的内置|运算符。但是,您必须更改方法的签名才能访问 Options 枚举类型而不是 ushort。

funcThatUsesOptns(Option.OPTN0 | Option.OPTN1);
[Flags]
public enum MyOptions : ushort {
    OPTN0 = 1 << 0,
    OPTN1 = 1 << 1,
    OPTN2 = 1 << 2,
    OPTN3 = 1 << 3,
}

这应该做你想要的。

我相信

最接近 2 个基元的运算符重载是制作扩展方法。 不幸的是,您将无法以这种方式执行真正的运算符重载,但这可能是一个可接受的解决方案:

public static ushort LogicalOr(this ushort s1, ushort s2)
{
    return (ushort)(s1 | s2);
}

funcThatUsesOptns(Option.OPTN1.LogicalOr(Option.OPTN2));

如果您可以更改函数签名,则像其他答案一样更改为枚举也是一个不错的解决方案。