Что сделать, когда битовая маска (флаги) перечисление становится слишком большой

Самое простое и чистое решение до ECMAScript-6 (которое также достаточно надежно, чтобы возвращать false, даже если в функцию передается не числовое значение, такое как строка или ноль):

function isInteger(x) { return (x^0) === x; } 

Следующее решение также будет работать, хотя и не так элегантно, как приведенное выше:

function isInteger(x) { return Math.round(x) === x; }

Обратите внимание , что Math.ceil () или Math.floor () могут использоваться одинаково хорошо (вместо Math.round ()) в приведенной выше реализации.

Или в качестве альтернативы:

function isInteger(x) { return (typeof x === 'number') && (x % 1 === 0); }

Одним из довольно распространенных неправильных решений является следующее:

function isInteger(x) { return parseInt(x, 10) === x; }

Хотя этот основанный на parseInt подход будет хорошо работать для многих значений x, один раз x становится довольно большим, он не сможет работать должным образом. Проблема в том, что parseInt () приводит свой первый параметр к строке перед разбором цифр. Следовательно, как только число станет достаточно большим, его строковое представление будет представлено в экспоненциальной форме (например, 1e + 21). Соответственно, parseInt () затем попытается проанализировать 1e + 21, но прекратит синтаксический анализ, когда достигнет символа e, и поэтому вернет значение 1. Наблюдение:

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

> parseInt(1000000000000000000000, 10) === 1000000000000000000000
false
70
задан Matthew Vines 29 June 2009 в 21:50
поделиться

6 ответов

Я вижу значения по крайней мере из нескольких различных перечислений ...

Моей первой мыслью было подойти к проблеме, разделив разрешения на логические группы ( RuleGroupPermissions , RulePermissions , LocationPermissions , ...), а затем наличие класса ( WebAgentPermissions ), предоставляющего свойство для каждого типа перечисления разрешений.

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

[Flags]
public enum Permissions
{
    View = 1,
    Add = 2,
    Edit = 4,
    Delete = 8
}

А затем пусть класс WebAgentPermissions предоставит свойство для каждой области, где должны быть установлены разрешения;

class WebAgentPermissions
{
    public Permissions RuleGroup { get; set; }
    public Permissions Rule{ get; set; }
    public Permissions Location{ get; set; }
    // and so on...
}
]
37
ответ дан 24 November 2019 в 13:29
поделиться

Если я могу подключить свой собственный модуль: я бы посоветовал использовать File :: Map вместо Sys :: Mmap . Его гораздо проще использовать и он менее подвержен сбоям, чем Sys :: Mmap.

http://msdn.microsoft.com/en-us/library/ms182147 (VS.80) .aspx

Int32 - это только тип данных DEFAULT! Фактически, вы можете указать Int64.

public enum MyEnumType : Int64

..., разрешив до 64 значений. Но это определенно кажется максимумом, после чего вы будете заниматься реинжинирингом. Не зная слишком много об остальной части вашего решения, я не могу точно сказать, что может подойти. Но массив (или хэш-карта) идентификаторов привилегий, вероятно, является наиболее естественным подходом.

http://msdn.microsoft.com/en-us/library/ms182147 (VS.80) .aspx

Int32 - это только тип данных DEFAULT! Фактически, вы можете указать Int64.

public enum MyEnumType : Int64

..., разрешив до 64 значений. Но это определенно кажется максимумом, после чего вы будете заниматься реинжинирингом. Не зная слишком много об остальной части вашего решения, я не могу точно сказать, что может подойти. Но массив (или хэш-карта) идентификаторов привилегий, вероятно, является наиболее естественным подходом.

21
ответ дан 24 November 2019 в 13:29
поделиться

Вы можете проверить класс BitArray . Возможно, вы воспользуетесь им в будущем.

13
ответ дан 24 November 2019 в 13:29
поделиться

В C # одним из гибких способов представления значения, которое является своего рода перечислением, но более гибким, является представление его в виде статического класса с доступными предварительно приготовленными значениями, например:

public sealed class WebAgentPermission
{
    private long ID;

    public static readonly WebAgentPermission
        ViewRuleGroup = new WebAgentPermission { ID = 1 };
    public static readonly WebAgentPermission
        AddRuleGroup  = new WebAgentPermission { ID = 2 };

    private WebAgentPermission() { } 

    // considerations: override equals/gethashcode, probably override tostring,
    // maybe implicit cast to/from long, maybe other stuff
}

В качестве альтернативы, просто разделите вещь вверх; похоже, вы могли бы, если бы действительно постарались.

5
ответ дан 24 November 2019 в 13:29
поделиться

Я не был в этой ситуации.

Вот что я думаю: создать отдельные перечисления для каждой категории и принять их как параметры.

RuleGroupPermission
    None = 0
    ViewRuleGroup = 1,
    AddRuleGroup = 2,
    EditRuleGroup = 4,
    DeleteRuleGroup = 8,

LocationOperations
    None = 0
    Add = 1
    View = 2
    Delete = 4

void setPermission(RuleGroupPermission ruleGroupOpsAllowed, LocationOperations locationOptions)
{
   ...
}

РЕДАКТИРОВАТЬ: Посмотрите, как окно сообщений .show делает это. ОК, ОК Отмена отделена от Вопроса, Информация, Восклицательный знак.

1
ответ дан 24 November 2019 в 13:29
поделиться

Если бы я контролировал это приложение, я бы, вероятно, придумал общий набор разрешений (Просмотр, Добавление, Редактирование, Удаление, Выгрузка / Импорт) и набор ресурсов (Пользователи , Роли, правила и т. Д.). На веб-странице найдите тип ресурса, связанный с этой страницей, а затем проверьте разрешения. Возможно, что-то вроде:

Permissions perms = agent.GetPermissions(ResourceType.User);
if((perms & Permissions.View) == Permissions.View) { /* do work */ }

или

Permissions perms = agent.Permissions[ResourceType.User];
if((perms & Permissions.View) == Permissions.View) { /* do work */ }

или даже

if(agent.IsAuthorized(ResourceType.User, Permissions.View)) { /* do work */ }

. У вас есть пара разрешений, которые не имеют смысла ни со всем остальным (Назначьте Permissoins пользователю, чтобы назвать одно). Я не уверен, как бы я справился с этим, исходя из того, насколько мало я знаю о проблеме.

4
ответ дан 24 November 2019 в 13:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: