简体   繁体   English

十进制到二进制位图和linq

[英]Decimal to binary bit map and linq

I have an application that use binary/hex a lot to determine if settings are enabled or not. 我有一个经常使用二进制/十六进制来确定设置是否启用的应用程序。 This is probably common practice but I'm new to programming so I wont know. 这可能是常见的做法,但是我是编程新手,所以我不知道。

Setting 1 = 1
Setting 2 = 2
Setting 3 = 4

The number reported in the database would be a total of all the enabled settings, eg 7. The implies that all three settings must be enabled as the sum equals 7. 数据库中报告的数字将是所有已启用设置的总数,例如7。这意味着必须启用所有三个设置,因为总和等于7。

I've made a tuple to report if the respective setting is enabled/disabled. 我做了一个元组来报告相应的设置是否启用/禁用。

    public static Tuple<int, string, string, string, string> mytuple(int value)
    {
        switch (value.ToString())
        {
            case "1":
                return new Tuple<int, string, string, string, string>(value, "Disabled", "Disabled", "Disabled", "Enabled");
            case "2":
                return new Tuple<int, string, string, string, string>(value, "Disabled", "Disabled", "Enabled", "Disabled");
            case "3":
                return new Tuple<int, string, string, string, string>(value, "Disabled", "Disabled", "Enabled", "Enabled");
            case "4":
                return new Tuple<int, string, string, string, string>(value, "Disabled", "Enabled", "Disabled", "Disabled");
            case "5":
                return new Tuple<int, string, string, string, string>(value, "Disabled", "Enabled", "Disabled", "Enabled");
            case "6":
                return new Tuple<int, string, string, string, string>(value, "Disabled", "Enabled", "Enabled", "Disabled");
            case "7":
        return new Tuple<int, string, string, string, string>(value, "Disabled", "Enabled", "Enabled", "Enabled");              
            case "8":
        return new Tuple<int, string, string, string, string>(value, "Enabled", "Disabled", "Disabled", "Disabled");
        }

        return new Tuple<int, string, string, string, string>(0, "", "", "", "");
    }

My question is, is there a simpler way to do this since its binary and the input value, 7 (binary 111) for instance can only be derived in one way ie all 3 settings enabled, or 4 (binary 100) for instance is one enabled rest disabled. 我的问题是,有没有一种更简单的方法,因为它的二进制和输入值7(例如二进制111)只能以一种方式导出,即所有3个设置都启用,或者例如4(二进制100)是一个启用休息已禁用。

Can one make a method to determine which bits are on / off instead having this giant tuple (the actual one runs up to 2048 so the list if very long). 可以用一种方法来确定打开/关闭哪些位,而不用拥有这个巨大的元组(实际的位元组最多可以运行2048,因此列表很长)。

EDIT 编辑

I've reviewed all your suggestions and came up with the following after more googling. 我已审核了您的所有建议,并在进一步谷歌搜索后提出了以下建议。

    static bool[] bitreader(int input)
    {
        int value = input;

        BitArray b = new BitArray(new int[] { value });

        bool[] bits = new bool[b.Count];
        b.CopyTo(bits, 0);

        return bits;
    }

    public void getnotitype(int input, out XElement notitype)
    {
        bool[] f = bitreader(input);

        notitype = (new XElement(("NotificationType"),
                (new XElement("NotifyUsingMessengerService", f[12])),
                (new XElement("SendEmail", f[13])),
                (new XElement("RunCustomCommand", f[14])),
                (new XElement("LogEvent", f[15]))));
    }

    public void getnotiact(int input, out XElement notiact)
    {
        bool[] f = bitreader(input);

        notiact = (new XElement(("MessengerEventLog"),
        (new XElement("LoggingEnabled", f[0])),
        (new XElement("Severe", f[1])),
        (new XElement("Warning", f[2])),
        (new XElement("Informational", f[3])),
        (new XElement("NotifyUser", f[5])),
        (new XElement("SendSNMP", f[6])),
        (new XElement("NotifyAdmin", f[7])),
        (new XElement("SendToAudit", f[11]))));
    }

Its working fine, does it look OK? 它工作正常,看起来还可以吗?

You can use binary conversion and use the output. 您可以使用二进制转换并使用输出。

int value = 7;
int toBase = 2;

//output is a list of characters with 1's and 0's
var output = Convert.ToString(value, toBase).ToList(); 
// gives you list of true/false
var listOfBools = output.Select(x => x=='1'?true:false); 
// gives you list of enabled/disabled string
var listOfStrings = output.Select(x => x=='1'?"enabled":"disabled");

you can loop through the char in the output to get your enabled or disabled key. 您可以遍历output的char来获取启用或禁用的密钥。

I would suggest one of the following two examples: 我建议以下两个示例之一:

1. Use flags with an Enum. 1.使用带有枚举的标志。

What does the [Flags] Enum Attribute mean in C#? C#中的[Flags]枚举属性是什么意思?

I could write more about Flags here, but the whole Flags-concept is covered pretty good in the link above. 我可以在这里写更多有关Flags的内容,但是在上面的链接中,整个Flags概念都相当不错。

[Flags]
public enum Setting
{
    Setting1 = 1,
    Setting2 = 2,
    Setting3 = 4,
    Setting4 = 8
}

private Setting GetSetting()
{
    Setting foo =  Setting.Setting1 | Setting.Setting2 | Setting.Setting3;
    return foo;
}

2. Use ConfigurationSetting . 2.使用ConfigurationSetting

Instead of using the Tuple the way you do, you can wrap all the settings in a class instead. 您可以将所有设置包装在一个类中,而不是像您那样使用Tuple By using ConfigurationSection you will also be able to store it in your app/web.config. 通过使用ConfigurationSection您还可以将其存储在app / web.config中。

public class MySettings : ConfigurationSection
{
    /// <summary>
    /// Some setting description here...
    /// </summary>
    [ConfigurationProperty("setting1",
        DefaultValue = false,
        IsRequired = true)]
    public bool Setting1
    {
        get { return (bool)this["setting1"]; }
    }
}

public class Foo
{
    public static MySettings GetSettings()
    {
        // Load settings from your configuration.
        return ConfigurationManager.GetSection("mySettings") as MySettings;
    }
}

And in your config something like this: 在您的配置中,如下所示:

<configSections>
    <section name="mySettings" type="YourNameSpace.MySettings, YourAssembly, Version=1.0.0.0, Culture=neutral"></section>
</configSections>
<mySettings setting1="true" />

Use a [Flags] enum. 使用[Flags]枚举。

[Flags]
public enum Status
{
    Setting1Enabled = 1,
    Setting2Enabled = 2,
    Setting3Enabled = 4
}

That way you can parse your int to an enum that supports bitwise comparisons. 这样,您就可以将int解析为支持按位比较的枚举。

To convert an Integer to that enum use Enum.Parse() 要将Integer转换为该枚举,请使用Enum.Parse()

Status status = Enum.Parse(typeof(Status), value);

And to check a certain value you can just compare it against the respective enum value. 要检查某个值,您可以将其与相应的枚举值进行比较。

I'd use an Enum for your settings and use bitwise operations to set them and check if the flags are set: 我将使用一个Enum进行设置,并使用按位操作来设置它们,并检查标志是否已设置:

[Flags]
enum MyEnum
{
    Setting1 = 1,
    Setting2 = 2,
    Setting3 = 4,
    Setting4 = 8
}

class Program
{
    static void Main(string[] args)
    {
        var myEnum = MyEnum.Setting1;

        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting1));
        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting2));
        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting3));

        myEnum = MyEnum.Setting2;

        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting1));
        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting2));
        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting3));

        myEnum = MyEnum.Setting2 | MyEnum.Setting3;

        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting1));
        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting2));
        Console.WriteLine(myEnum.HasFlag(MyEnum.Setting3));

        Console.ReadLine();
    }
}

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

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