gpt4 book ai didi

c# - 如何声明嵌套枚举?

转载 作者:IT王子 更新时间:2023-10-29 03:53:07 27 4
gpt4 key购买 nike

我想声明一个嵌套的枚举:

\\pseudocode
public enum Animal
{
dog = 0,
cat = 1
}

private enum dog
{
bulldog = 0,
greyhound = 1,
husky = 3
}

private enum cat
{
persian = 0,
siamese = 1,
burmese = 2
}

Animal patient1 = Animal.dog.husky;

可以吗?

最佳答案

我一直在寻找类似于为日志系统创建轻量级、分层 channel ID 的方法。我不太确定这是否值得付出努力,但我把它们放在一起很有趣,并且我在这个过程中学到了一些关于运算符重载和蜥蜴的新知识。

我已经建立了一个支持这种表示法的机制:

public static class Animal
{
public static readonly ID dog = 1;
public static class dogs
{
public static readonly ID bulldog = dog[0];
public static readonly ID greyhound = dog[1];
public static readonly ID husky = dog[3];
}

public static readonly ID cat = 2;
public static class cats
{
public static readonly ID persian = cat[0];
public static readonly ID siamese = cat[1];
public static readonly ID burmese = cat[2];
}

public static readonly ID reptile = 3;
public static class reptiles
{
public static readonly ID snake = reptile[0];
public static class snakes
{
public static readonly ID adder = snake[0];
public static readonly ID boa = snake[1];
public static readonly ID cobra = snake[2];
}

public static readonly ID lizard = reptile[1];
public static class lizards
{
public static readonly ID gecko = lizard[0];
public static readonly ID komodo = lizard[1];
public static readonly ID iguana = lizard[2];
public static readonly ID chameleon = lizard[3];
}
}
}

你可以这样使用:

void Animalize()
{
ID rover = Animal.dogs.bulldog;
ID rhoda = Animal.dogs.greyhound;
ID rafter = Animal.dogs.greyhound;

ID felix = Animal.cats.persian;
ID zorro = Animal.cats.burmese;

ID rango = Animal.reptiles.lizards.chameleon;

if (rover.isa(Animal.dog))
Console.WriteLine("rover is a dog");
else
Console.WriteLine("rover is not a dog?!");

if (rover == rhoda)
Console.WriteLine("rover and rhoda are the same");

if (rover.super == rhoda.super)
Console.WriteLine("rover and rhoda are related");

if (rhoda == rafter)
Console.WriteLine("rhoda and rafter are the same");

if (felix.isa(zorro))
Console.WriteLine("er, wut?");

if (rango.isa(Animal.reptile))
Console.WriteLine("rango is a reptile");

Console.WriteLine("rango is an {0}", rango.ToString<Animal>());
}

该代码编译并产生以下输出:

rover is a dog
rover and rhoda are related
rhoda and rafter are the same
rango is a reptile
rango is an Animal.reptiles.lizards.chameleon

这是使其工作的 ID 结构:

public struct ID
{
public static ID none;

public ID this[int childID]
{
get { return new ID((mID << 8) | (uint)childID); }
}

public ID super
{
get { return new ID(mID >> 8); }
}

public bool isa(ID super)
{
return (this != none) && ((this.super == super) || this.super.isa(super));
}

public static implicit operator ID(int id)
{
if (id == 0)
{
throw new System.InvalidCastException("top level id cannot be 0");
}
return new ID((uint)id);
}

public static bool operator ==(ID a, ID b)
{
return a.mID == b.mID;
}

public static bool operator !=(ID a, ID b)
{
return a.mID != b.mID;
}

public override bool Equals(object obj)
{
if (obj is ID)
return ((ID)obj).mID == mID;
else
return false;
}

public override int GetHashCode()
{
return (int)mID;
}

private ID(uint id)
{
mID = id;
}

private readonly uint mID;
}

这利用了:

  • 作为基础类型的 32 位 uint
  • 多个小数字通过移位填充到一个整数中(您可以获得最多四层嵌套 ID,每层有 256 个条目——您可以转换为 ulong 以获得更多层或每层更多位)
  • ID 0 作为所有 ID 的特殊根(可能 ID.none 应该称为 ID.root,并且任何 id.isa(ID.root) 应该为真)
  • implicit type conversion将 int 转换为 ID
  • 一个indexer将 ID 链接在一起
  • overloaded equality operators支持比较

到目前为止,一切都非常高效,但我不得不求助于 ToString 的反射和递归,所以我在 extension method 中将其封锁,如下:

using System;
using System.Reflection;

public static class IDExtensions
{
public static string ToString<T>(this ID id)
{
return ToString(id, typeof(T));
}

public static string ToString(this ID id, Type type)
{
foreach (var field in type.GetFields(BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static))
{
if ((field.FieldType == typeof(ID)) && id.Equals(field.GetValue(null)))
{
return string.Format("{0}.{1}", type.ToString().Replace('+', '.'), field.Name);
}
}

foreach (var nestedType in type.GetNestedTypes())
{
string asNestedType = ToString(id, nestedType);
if (asNestedType != null)
{
return asNestedType;
}
}

return null;
}
}

请注意,要使其正常工作,Animal 不能再是静态类,因为 static classes can't be used as type parameters ,所以我改为使用私有(private)构造函数将其密封:

public /*static*/ sealed class Animal
{
// Or else: error CS0718: 'Animal': static types cannot be used as type arguments
private Animal()
{
}
....

呸!谢谢阅读。 :-)

关于c# - 如何声明嵌套枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/980766/

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