C#enum添加

时间:2010-02-09 16:57:02

标签: c# enums

问候,我有以下枚举:

    public enum LegalShipTypes : byte
    {
        Frigate = 1,
        Cruiser = 2,
        Destroyer = 3,
        Submarine = 4,
        AircraftCarrier = 5
    }

我想知道是否有办法以任何方式获得枚举的总价值。例如,这将导致(1 + 2 + 3 + 4 + 5)= 15。

谢谢。

7 个答案:

答案 0 :(得分:8)

如果您可以编辑枚举,并且您需要在很多地方使用它们的总和,您可以将它放在枚举中:

public enum LegalShipTypes : byte {
  Frigate = 1,
  Cruiser = 2,
  Destroyer = 3,
  Submarine = 4,
  AircraftCarrier = 5,
  All = Frigate + Cruiser + Destroyer + Submarine + AircraftCarrier
} 

这在标志枚举中更有意义:

[Flags]
public enum LegalShipTypes : byte {
  Frigate = 1,
  Cruiser = 2,
  Destroyer = 4,
  Submarine = 8,
  AircraftCarrier = 16,
  All = Frigate | Cruiser | Destroyer | Submarine | AircraftCarrier
} 

或者你可以使用它:

Enum.GetValues(typeof(LegalShipTypes)).Cast<byte>().Sum(x=>x)

返回decimal

但这是一种更通用的方法(无论枚举的基础类型如何都有效):

public decimal Sum(Type enumType) {
  return Enum
    .GetValues(enumType)
    .Cast<object>()
    .Sum(x => (decimal)Convert.ChangeType(x, typeof(decimal)));
}

答案 1 :(得分:6)

我不想输入这个作为答案,因为它不会直接回答您的问题,但根据您对我的问题的评论的评论,这值得一些解释。

枚举是非常简单的类型安全的状态表示。如果只使用常量,则可以将错误的常量分配给值。这可以防止您为字段分配错误类型的常量。例如,如果你有一些期望DayOfWeek的东西,你就不能分配FileAccess值,即使它们都是相同底层类型的常量。

DayOfWeek day = FileAccess.Write; // doesn't work

如果你需要这种类型的安全性,你不需要你的枚举表现出任何其他类型的行为,那么使用枚举。如果你关心你的枚举也做其他事情(比如枚举,数学运算等),那么你应该考虑使用类。请参阅下面的示例。

public class LegalShipTypes
{
    private readonly byte _numericValue;
    private readonly string _text;

    private LegalShipTypes(byte numericValue, string text)
    {
        _numericValue = numericValue;
        _text = text;
    }

    public byte Value { get { return _numericValue; } }
    public string Text { get { return _text; } }

    public static IEnumerable<LegalShipTypes> All
    {
        get
        {
            return new[] { Frigate, Cruiser, Destroyer, Submarine, AircraftCarrier };
        }
    }

    public static readonly LegalShipTypes Frigate = new LegalShipTypes(1, "Frigate");
    public static readonly LegalShipTypes Cruiser = new LegalShipTypes(2, "Cruiser");
    public static readonly LegalShipTypes Destroyer = new LegalShipTypes(3, "Destroyer");
    public static readonly LegalShipTypes Submarine = new LegalShipTypes(4, "Submarine");
    public static readonly LegalShipTypes AircraftCarrier = new LegalShipTypes(5, "Aircraft Carrier");
}

现在你可以像这样使用类型安全的方式使用它:

public class Fleet
{
    private readonly List<LegalShipTypes> _ships;

    public Fleet()
    {
        _ships = new List<LegalShipTypes>();
    }

    public LegalShipTypes Flagship { get; set; }
    public ICollection<LegalShipTypes> Ships { get { return _ships; } }
}

....

var fleet = new Fleet();
fleet.FlagShip = LegalShipTypes.AircraftCarrier;
var iDoNotKnowWhyYouWouldNeedThisBut = LegalShipTypes.All.Sum(ship => ship.Value);
Console.WriteLine("The flagship is a(n) \"{0}\".", fleet.FlagShip.Text);
if (fleet.FlagShip == LegalShipTypes.AircraftCarrier) // this will work because it's a reference comparison
    Console.WriteLine("This should be true");

正如您所看到的,您仍然具有类型安全性,但更具灵活性。这是更多的代码,但你不会发现自己正在努力克服枚举的局限性。重申一下,枚举意味着简单。它应该很简单。如果您的需求很简单,请不要犹豫,使用它。如果您的需求更加复杂,那么使用优秀的老式面向对象编程来解决您的问题并不是一件好事。

修改

根据您最后的评论回复,字节值表示挂钩的数量,我强烈建议您不要使用枚举来解决您的问题。 (具有讽刺意味的是)你试图在方孔中放一个圆钉。

答案 2 :(得分:5)

尝试以下假设它是一个继承自System.Int32的枚举(这是默认值)。

public int Sum(Type enumType) {
  return Enum.GetValues(enumType).Cast<int>().Sum();
}

编辑没有注意到OP的问题继承自byte。这是一个适用于byte

的版本
public int Sum(Type enumType) {
  return Enum.GetValues(enumType).Cast<byte>().Select(x => (int)x).Sum();
}

答案 3 :(得分:1)

请参阅此类似问题的接受答案:

How do I enumerate an enum?

您可以获取值,通过它们进行枚举,然后将for循环中的值相加。

答案 4 :(得分:0)

JaredPar对Luke纠正的答案的通用版本:

public int Sum<T>(Type enumType) {
    return Enum.GetValues(enumType).Cast<T>().Sum();
}

致电:

Sum<byte>(typeof(LegalShipTypes));

编辑: 好吧,抓住这个想法。我想:

public int Sum(Type enumType) {
    return Enum.GetValues(enumType).Cast<byte>().Sum();
}

就是答案。

答案 5 :(得分:0)

如果您想要对枚举器值求和,那么使用带标记的枚举器会不会更好?

答案 6 :(得分:0)

 public enum LegalShipTypes : byte
    {
        Frigate = 1,
        Cruiser = 2,
        Destroyer = 3,
        Submarine = 4,
        AircraftCarrier = 5
    }
    class Program
    {
        static void Main()
        {
            byte sum = 0;
            foreach (byte item in Enum.GetValues(typeof(LegalShipTypes)))
            {
                sum += (byte)(object)item;
            }

            Console.WriteLine(sum);
        }
    }