2014-12-19 5 views
1

Я использую класс в качестве оболочки для размещения группы из нескольких неподписанных шорт, которые представляют разные варианты или характеристики. Каждый короткий инициализируется как сила двух, поэтому я могу легко добавить или или их вместе.Перегрузка оператора для примитивных типов

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

Однако, поскольку «+» и «|» оба возвращают ints в этой ситуации, я должен бросать их каждый раз, когда я это делаю. Например, как а и Ь инициализируется как Интс:

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

Так мне было интересно, если перегрузка оператора было возможно для примитивных типов. Если нет, есть ли лучшие способы достижения этого? Конечно, я не собираюсь убивать меня, чтобы просто бросать его каждый раз, но я надеялся на более чистый путь.

Редактировать: Я использую это, чтобы отображать множество простых геометрических объектов (кубы, пирамиды, ...). Я хотел бы иметь возможность быстро сказать рендереру, который стоит рисовать. Если лицо на одном объекте касается другого или обращено от камеры, я могу установить соответствующий бит, чтобы сообщить визуализатору не рисовать это лицо.

+0

Почему бы не определить свои «параметры» как 'int' и изменить' funcThatUsesOptns', чтобы взять 'int'? – juharr

+0

По какой причине вы не используете Enums с атрибутом 'Flags'? –

+0

Я пробовал использовать флаги, но если я делал это неправильно (очень вероятно), мне все еще нужно было отличать – Camander

ответ

0

Похоже, что вы действительно хотите здесь значения перечислений на основе USHORT, как это:

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

Затем вы можете использовать встроенный | оператора для перечислений. Тем не менее, вы должны изменить подпись своих методов, чтобы получить доступ к типу перечисления Options вместо имени пользователя.

funcThatUsesOptns(Option.OPTN0 | Option.OPTN1); 
+0

Спасибо, это похоже на то, что я, вероятно, сделаю. еще один вопрос, однако, что было бы лучшим способом проверки отдельных бит на другой стороне? – Camander

+1

Ahh. Nevermind, функция HasFlag выглядит так, как будто она будет работать красиво :) – Camander

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

Это должно делать то, что вы хотите.

+0

К сожалению, он все еще заставляет меня бросить, когда я это делаю. – Camander

0

Я считаю, ближе вы получите к оператору перегрузки на 2 примитивов будет сделать метод расширения. К сожалению, вы не смогли бы сделать истинный оператор перегружать, что путь, но это может быть приемлемым решением:

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

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

Изменение в ENUM, как и другие ответы также является хорошим решением, если вы в порядке с изменениями подписей функций.