我在一个低级名称空间中有一个枚举。我想在中层名称空间中提供一个“继承”低层枚举的类或枚举。
namespace low
{
public enum base
{
x, y, z
}
}
namespace mid
{
public enum consume : low.base
{
}
}
我希望这是可能的,或者可能有某种类可以取代枚举消费,这将为枚举提供一个抽象层,但仍然让该类的实例访问枚举。
想法吗?
编辑:
我没有在类中将其转换为const的原因之一是我必须使用的服务需要低级枚举。我已经获得了wsdl和xsd,它们将结构定义为枚举。该服务不可更改。
我还想重载枚举,并在本页上创建了“七个”的答案和“梅林摩根-格雷厄姆”的答案的混合,再加上一些改进。
我的解决方案相对于其他解决方案的主要优势:
基础int值的自动递增
自动命名
这是一个开箱即用的解决方案,可以直接插入到您的项目中。它是根据我的需要设计的,所以如果你不喜欢它的某些部分,只需用你自己的代码替换它们。
首先,有一个基类CEnum,所有自定义枚举都应该继承它。它有基本的功能,类似于。net Enum类型:
public class CEnum
{
protected static readonly int msc_iUpdateNames = int.MinValue;
protected static int ms_iAutoValue = -1;
protected static List<int> ms_listiValue = new List<int>();
public int Value
{
get;
protected set;
}
public string Name
{
get;
protected set;
}
protected CEnum ()
{
CommonConstructor (-1);
}
protected CEnum (int i_iValue)
{
CommonConstructor (i_iValue);
}
public static string[] GetNames (IList<CEnum> i_listoValue)
{
if (i_listoValue == null)
return null;
string[] asName = new string[i_listoValue.Count];
for (int ixCnt = 0; ixCnt < asName.Length; ixCnt++)
asName[ixCnt] = i_listoValue[ixCnt]?.Name;
return asName;
}
public static CEnum[] GetValues ()
{
return new CEnum[0];
}
protected virtual void CommonConstructor (int i_iValue)
{
if (i_iValue == msc_iUpdateNames)
{
UpdateNames (this.GetType ());
return;
}
else if (i_iValue > ms_iAutoValue)
ms_iAutoValue = i_iValue;
else
i_iValue = ++ms_iAutoValue;
if (ms_listiValue.Contains (i_iValue))
throw new ArgumentException ("duplicate value " + i_iValue.ToString ());
Value = i_iValue;
ms_listiValue.Add (i_iValue);
}
private static void UpdateNames (Type i_oType)
{
if (i_oType == null)
return;
FieldInfo[] aoFieldInfo = i_oType.GetFields (BindingFlags.Public | BindingFlags.Static);
foreach (FieldInfo oFieldInfo in aoFieldInfo)
{
CEnum oEnumResult = oFieldInfo.GetValue (null) as CEnum;
if (oEnumResult == null)
continue;
oEnumResult.Name = oFieldInfo.Name;
}
}
}
其次,这里有2个派生的Enum类。所有派生类都需要一些基本方法才能正常工作。它总是相同的样板代码;我还没有找到将它外包给基类的方法。继承的第一级的代码与所有后续级略有不同。
public class CEnumResult : CEnum
{
private static List<CEnumResult> ms_listoValue = new List<CEnumResult>();
public static readonly CEnumResult Nothing = new CEnumResult ( 0);
public static readonly CEnumResult SUCCESS = new CEnumResult ( 1);
public static readonly CEnumResult UserAbort = new CEnumResult ( 11);
public static readonly CEnumResult InProgress = new CEnumResult (101);
public static readonly CEnumResult Pausing = new CEnumResult (201);
private static readonly CEnumResult Dummy = new CEnumResult (msc_iUpdateNames);
protected CEnumResult () : base ()
{
}
protected CEnumResult (int i_iValue) : base (i_iValue)
{
}
protected override void CommonConstructor (int i_iValue)
{
base.CommonConstructor (i_iValue);
if (i_iValue == msc_iUpdateNames)
return;
if (this.GetType () == System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType)
ms_listoValue.Add (this);
}
public static new CEnumResult[] GetValues ()
{
List<CEnumResult> listoValue = new List<CEnumResult> ();
listoValue.AddRange (ms_listoValue);
return listoValue.ToArray ();
}
}
public class CEnumResultClassCommon : CEnumResult
{
private static List<CEnumResultClassCommon> ms_listoValue = new List<CEnumResultClassCommon>();
public static readonly CEnumResult Error_InternalProgramming = new CEnumResultClassCommon (1000);
public static readonly CEnumResult Error_Initialization = new CEnumResultClassCommon ();
public static readonly CEnumResult Error_ObjectNotInitialized = new CEnumResultClassCommon ();
public static readonly CEnumResult Error_DLLMissing = new CEnumResultClassCommon ();
// ... many more
private static readonly CEnumResult Dummy = new CEnumResultClassCommon (msc_iUpdateNames);
protected CEnumResultClassCommon () : base ()
{
}
protected CEnumResultClassCommon (int i_iValue) : base (i_iValue)
{
}
protected override void CommonConstructor (int i_iValue)
{
base.CommonConstructor (i_iValue);
if (i_iValue == msc_iUpdateNames)
return;
if (this.GetType () == System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType)
ms_listoValue.Add (this);
}
public static new CEnumResult[] GetValues ()
{
List<CEnumResult> listoValue = new List<CEnumResult> (CEnumResult.GetValues ());
listoValue.AddRange (ms_listoValue);
return listoValue.ToArray ();
}
}
这些类已经通过以下代码成功测试:
private static void Main (string[] args)
{
CEnumResult oEnumResult = CEnumResultClassCommon.Error_Initialization;
string sName = oEnumResult.Name; // sName = "Error_Initialization"
CEnum[] aoEnumResult = CEnumResultClassCommon.GetValues (); // aoEnumResult = {testCEnumResult.Program.CEnumResult[9]}
string[] asEnumNames = CEnum.GetNames (aoEnumResult);
int ixValue = Array.IndexOf (aoEnumResult, oEnumResult); // ixValue = 6
}
这样做的方法(如果有必要的话)是实现自己的类结构,其中包括您希望从继承枚举的概念中获得的特性,而且您还可以添加更多特性。
您只需实现相等比较器和函数来查找您自己编写的值。
您可以将构造函数设为私有,并声明类和任何子类的静态实例。
或者为您的问题找到一个简单的解决方法,并坚持使用本机枚举实现。
继承枚举的重代码实现:
/// <summary>
/// Generic Design for implementing inheritable enum
/// </summary>
public class ServiceBase
{
//members
protected int _id;
protected string _name;
//constructors
private ServiceBase(int id, string name)
{
_id = id;
_name = name;
}
//onlu required if subclassing
protected ServiceBase(int id, string name, bool isSubClass = true )
{
if( id <= _maxServiceId )
throw new InvalidProgramException("Bad Id in ServiceBase" );
_id = id;
_name = name;
}
//members
public int Id => _id;
public string Name => _name;
public virtual ServiceBase getService(int serviceBaseId)
{
return ALLBASESERVICES.SingleOrDefault(s => s.Id == _id);
}
//implement iComparable if required
//static methods
public static ServiceBase getServiceOrDefault(int serviceBaseId)
{
return SERVICE1.getService(serviceBaseId);
}
//Enumerations Here
public static ServiceBase SERVICE1 = new ServiceBase( 1, "First Service" );
public static ServiceBase SERVICE2 = new ServiceBase( 2, "Second Service" );
protected static ServiceBase[] ALLBASESERVICES =
{
//Enumerations list
SERVICE1,
SERVICE2
};
private static int _maxServiceId = ALLBASESERVICES.Max( s => s.Id );
//only required if subclassing
protected static ServiceBase[] combineServices(ServiceBase[] array1, ServiceBase[] array2)
{
List<ServiceBase> serviceBases = new List<ServiceBase>();
serviceBases.AddRange( array1 );
serviceBases.AddRange( array2 );
return serviceBases.ToArray();
}
}
/// <summary>
/// Generic Design for implementing inheritable enum
/// </summary>
public class ServiceJobs : ServiceBase
{
//constructor
private ServiceJobs(int id, string name)
: base( id, name )
{
_id = id;
_name = name;
}
//only required if subclassing
protected ServiceJobs(int id, string name, bool isSubClass = true )
: base( id, name )
{
if( id <= _maxServiceId )
throw new InvalidProgramException("Bad Id in ServiceJobs" );
_id = id;
_name = name;
}
//members
public override ServiceBase getService(int serviceBaseId)
{
if (ALLSERVICES == null)
{
ALLSERVICES = combineServices(ALLBASESERVICES, ALLJOBSERVICES);
}
return ALLSERVICES.SingleOrDefault(s => s.Id == _id);
}
//static methods
public static ServiceBase getServiceOrDefault(int serviceBaseId)
{
return SERVICE3.getService(serviceBaseId);
}
//sub class services here
public static ServiceBase SERVICE3 = new ServiceJobs( 3, "Third Service" );
public static ServiceBase SERVICE4 = new ServiceJobs( 4, "Forth Service" );
private static int _maxServiceId = ALLJOBSERVICES.Max( s => s.Id );
private static ServiceBase[] ALLJOBSERVICES =
{
//subclass service list
SERVICE3,
SERVICE4
};
//all services including superclass items
private static ServiceBase[] ALLSERVICES = null;
}
注意,您可以使用枚举而不是int作为id,尽管子类需要一个单独的枚举。
枚举类本身可以用各种标志、消息、函数等来装饰。
泛型实现将减少大量代码。