简体   繁体   English

原始类型的运算符重载

[英]operator overloading for primitive types

I am using a class as a wrapper to hold a group of several unsigned shorts that represent different options or characteristics. 我使用一个类作为包装器来容纳一组代表不同选项或特征的无符号短裤。 Each short is initialized to be a power of two so I can easily add or or them together. 每条短裤被初始化为2的幂,因此我可以轻松地将or或它们加在一起。

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
    ...
}

However, since "+" and "|" 但是,由于“ +”和“ |” both return ints in this situation, I have to cast them every time I do. 两者都返回int在这种情况下,我每次都必须强制转换它们。 For example, both a and b are initialized as ints: 例如,a和b都初始化为int:

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

So I was wondering if operator overloading was possible for primitive types. 因此,我想知道原始类型是否可能发生运算符重载。 If not, are there any better ways of achieving this? 如果没有,是否有更好的方法来实现这一目标? Of course it isn't going to kill me to just cast it every time, but I was hoping for a cleaner way. 当然,每次都抛弃它并不会杀死我,但我希望有一种更清洁的方法。

Edit: I am actually using this to render a lot of simple geometric objects (cubes, pyramids,...). 编辑:我实际上是用它来渲染很多简单的几何对象(立方体,金字塔等)。 I would like to be able to quickly tell the renderer which faces to draw. 我希望能够快速告诉渲染器要绘制哪些面。 If a face on one object is touching another or is facing away from the camera, I can set the corresponding bit to tell the renderer not to draw that face. 如果一个对象上的某个面孔正在触摸另一对象或背对相机,则可以设置相应的位以告知渲染器不要绘制该面孔。

[Flags]
public enum MyOptions : ushort {
    OPTN0 = 1 << 0,
    OPTN1 = 1 << 1,
    OPTN2 = 1 << 2,
    OPTN3 = 1 << 3,
}

This should do what you want. 这应该做您想要的。

It seems like what you really want here are enum values based on ushort, like this: 似乎您真正想要的是基于ushort的枚举值,如下所示:

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

Then you can make use of the built-in | 然后,您可以使用内置| operator for enums. 枚举的运算符。 You would, however, have to change the signature of your methods to access the Options enum type instead of a ushort. 但是,您必须更改方法的签名才能访问Options枚举类型,而不是ushort。

funcThatUsesOptns(Option.OPTN0 | Option.OPTN1);

I believe the closest you'll get to operator overloading on 2 primitives would be making an extension method. 我相信,最接近2个原语的运算符重载将是一种扩展方法。 Unfortunately you wouldn't be able to do a true operator overload that way, but it might be an acceptable solution: 不幸的是,您将无法以这种方式进行真正的运算符重载,但这可能是可以接受的解决方案:

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

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

Changing to enum like the other answers is also a good solution if you are OK with changing your function signatures. 如果可以更改函数签名,则像其他答案一样更改为枚举也是一个很好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM