gpt4 book ai didi

c# - 确定枚举值是否不是 C# 中的复合值

转载 作者:太空狗 更新时间:2023-10-30 00:31:37 25 4
gpt4 key购买 nike

编辑:

大多数人建议标志枚举的值应始终为 2 的幂。这可能是最佳实践,但我不是在这里定义枚举,而是检查它们并希望在合理范围内涵盖所有可能的场景。问题实际上是关于实现名为 EnumUtilities.IsValueDefinedAndComposite<T> 的函数的正确方法。 .

原帖:

考虑以下枚举:

[Flags]
public enum TestWithFlags { One = 1, Two = 2, }

以下是 Enum.IsDefined 的结果具有各种值类型转换为 TestWithFlags .

输出:

(1). Defined: True:  One.
(2). Defined: True: Two.
(3). Defined: False: 100.
(4). Defined: False: One, Two.
(5). Defined: ?????: One, Two.

我想不通的是如何确定枚举值是复合值。请看函数EnumUtilities.IsValueDefinedAndComposite<T>在下面的代码中。

为方便起见,这里是完整的代码。

using System;
using System.Collections.Generic;
using System.Linq;

namespace MyNamespace
{
[Flags]
public enum TestWithFlags { One = 1, Two = 2, }

public static class Program
{
private static void Main (string [] args)
{
TestWithFlags value;

value = TestWithFlags.One; // True.
Console.WriteLine("(1). Defined: {0}: {1}.", Enum.IsDefined(typeof(TestWithFlags), value), value.ToString());

value = TestWithFlags.Two; // True.
Console.WriteLine("(2). Defined: {0}: {1}.", Enum.IsDefined(typeof(TestWithFlags), value), value.ToString());

value = (TestWithFlags) 100; // False.
Console.WriteLine("(3). Defined: {0}: {1}.", Enum.IsDefined(typeof(TestWithFlags), value), value.ToString());

value = TestWithFlags.One | TestWithFlags.Two; // False.
Console.WriteLine("(4). Defined: {0}: {1}.", Enum.IsDefined(typeof(TestWithFlags), value), value.ToString());

value = TestWithFlags.One | TestWithFlags.Two; // Not implemented.
Console.WriteLine("(5). Defined: N/A: {1}.", EnumUtilities.IsValueDefinedAndComposite(value), value.ToString());

Console.WriteLine();
Console.Write("Press any key to continue...");
Console.ReadKey(true);
}
}

public static class EnumUtilities
{
public static List<T> GetValues<T> ()
where T: struct, IComparable, IFormattable, IConvertible
{
EnumUtilities.ThrowOnNonEnum<T>();

var list = Enum.GetValues(typeof(T)).OfType<T>().ToList().ConvertAll<T>(v => ((T) v));

return (list);
}

public static bool IsValueDefinedAndComposite<T> (T value)
where T: struct, IComparable, IFormattable, IConvertible
{
EnumUtilities.ThrowOnEnumWithoutFlags<T>();

var values = EnumUtilities.GetValues<T>();

var result = false;
//var result = values.Count(v => (value | v) == value) > 1;
// How to determine whether the argument [value] is composite.

return (result);
}

public static bool IsValueDefinedAndNonComposite<T> (T value)
where T: struct, IComparable, IFormattable, IConvertible
{
EnumUtilities.ThrowOnNonEnum<T>();

return (Enum.IsDefined(typeof(T), value));
}

public static bool IsValueDefined<T> (T value)
where T: struct, IComparable, IFormattable, IConvertible
{
EnumUtilities.ThrowOnNonEnum<T>();

return (EnumUtilities.IsValueDefinedAndNonComposite(value) || EnumUtilities.IsValueDefinedAndComposite(value));
}

private static void ThrowOnNonEnum<T> ()
{
if (!typeof(T).IsEnum)
{
throw (new ArgumentException("The generic argument [<T>] must be an enumeration.", "T: " + typeof(T).FullName));
}
}

private static void ThrowOnEnumWithFlags<T> ()
{
EnumUtilities.ThrowOnNonEnum<T>();

var attributes = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false);

if (attributes.Length > 0)
{
throw (new ArgumentException("The generic argument [<T>] must be an enumeration without the [FlagsAttribute] applied.", "T: " + typeof(T).FullName));
}
}

private static void ThrowOnEnumWithoutFlags<T> ()
{
EnumUtilities.ThrowOnNonEnum<T>();

var attributes = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false);

if (attributes.Length == 0)
{
throw (new ArgumentException("The generic argument [<T>] must be an enumeration with the [FlagsAttribute] applied.", "T: " + typeof(T).FullName));
}
}
}
}

最佳答案

您可以尝试类似(未测试!):

   public static bool IsValueDefinedAndComposite<T>(T value)
where T : struct, IComparable, IFormattable, IConvertible
{
EnumUtilities.ThrowOnEnumWithoutFlags<T>();

var values = EnumUtilities.GetValues<T>();


var result = values.OfType<T>().Contains(value);
//var result = values.Count(v => (value | v) == value) > 1;
// How to determine whether the argument [value] is composite.

return (result);
}

基本上,它只是检查值参数是否是值的一部分,如果不是,则它是复合值。

关于c# - 确定枚举值是否不是 C# 中的复合值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24469941/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com