sourcetip

Enum "상속"

fileupload 2023. 5. 28. 21:01
반응형

Enum "상속"

하위 네임스페이스에 열거형이 있습니다.하위 수준 열거형을 "상속"하는 중간 수준 네임스페이스의 클래스 또는 열거형을 제공하려고 합니다.

namespace low
{
   public enum base
   {
      x, y, z
   }
}

namespace mid
{
   public enum consume : low.base
   {
   }
}

저는 이것이 가능하기를 희망합니다. 또는 아마도 열거 소비를 대신할 수 있는 일종의 클래스가 열거에 대한 추상화 계층을 제공하지만 여전히 해당 클래스의 인스턴스가 열거에 액세스할 수 있기를 바랍니다.

생각은?

편집: 수업 시간에 이것을 컨스트로 전환하지 않은 이유 중 하나는 낮은 수준의 열거형이 제가 사용해야 하는 서비스에 필요하기 때문입니다.구조를 열거형으로 정의하는 WSDL과 XSD를 받았습니다.서비스를 변경할 수 없습니다.

이것은 불가능합니다.열거형은 다른 열거형에서 상속할 수 없습니다.사실 모든 열거형은 실제로 다음에서 상속되어야 합니다.System.EnumC#을 사용하면 구문에서 상속처럼 보이는 열거형 값의 기본 표현을 변경할 수 있지만 실제로는 System.enum에서 상속됩니다.

자세한 내용은 CLI 사양의 섹션 8.5.2를 참조하십시오.사양의 관련 정보

  • 모든 열거형은 다음에서 파생되어야 합니다.System.Enum
  • 위와 같은 이유로 모든 열거형은 값 유형이므로 밀봉됩니다.

수업을 통해 원하는 것을 달성할 수 있습니다.

public class Base
{
    public const int A = 1;
    public const int B = 2;
    public const int C = 3;
}
public class Consume : Base
{
    public const int D = 4;
    public const int E = 5;
}

이제 이러한 클래스를 열거형이었을 때와 유사하게 사용할 수 있습니다.

int i = Consume.B;

업데이트(질문 업데이트 후):

기존 열거형에 정의된 상수에 동일한 int 값을 할당하면 열거형과 상수 사이에 캐스트할 수 있습니다. 예를 들어, 다음과 같습니다.

public enum SomeEnum // this is the existing enum (from WSDL)
{
    A = 1,
    B = 2,
    ...
}
public class Base
{
    public const int A = (int)SomeEnum.A;
    //...
}
public class Consume : Base
{
    public const int D = 4;
    public const int E = 5;
}

// where you have to use the enum, use a cast:
SomeEnum e = (SomeEnum)Consume.B;

간단히 말하면 아니오입니다.원하는 경우 조금만 재생할 수 있습니다.

언제든지 다음과 같은 작업을 수행할 수 있습니다.

private enum Base
{
    A,
    B,
    C
}

private enum Consume
{
    A = Base.A,
    B = Base.B,
    C = Base.C,
    D,
    E
}

하지만, 베이스 때문에 그렇게 잘 작동하지 않습니다.A!= 소비.a

언제든지 다음과 같은 작업을 수행할 수 있습니다.

public static class Extensions
{
    public static T As<T>(this Consume c) where T : struct
    {
        return (T)System.Enum.Parse(typeof(T), c.ToString(), false);
    }
}

기본값과 소비를 교차하려면...

열거형의 값을 int로 주조하고 열거형 대신 int로 비교할 수도 있지만, 그것도 좀 형편없습니다.

확장 메서드 반환은 cast it type T를 입력해야 합니다.

int 상수가 있는 클래스를 사용하는 위의 솔루션에는 형식 안전성이 부족합니다.즉, 클래스에서 실제로 정의되지 않은 새로운 값을 발명할 수 있습니다.또한 예를 들어 이러한 클래스 중 하나를 입력으로 사용하는 메서드를 작성할 수 없습니다.

당신은 글을 써야 할 것입니다.

public void DoSomethingMeaningFull(int consumeValue) ...

그러나 사용 가능한 열거형이 없었던 Java의 옛 시절에 대한 클래스 기반 솔루션이 있습니다.이는 거의 열거형과 같은 동작을 제공합니다.유일한 경고는 이러한 상수를 스위치 문 내에서 사용할 수 없다는 것입니다.

public class MyBaseEnum
{
    public static readonly MyBaseEnum A = new MyBaseEnum( 1 );
    public static readonly MyBaseEnum B = new MyBaseEnum( 2 );
    public static readonly MyBaseEnum C = new MyBaseEnum( 3 );

    public int InternalValue { get; protected set; }

    protected MyBaseEnum( int internalValue )
    {
        this.InternalValue = internalValue;
    }
}

public class MyEnum : MyBaseEnum
{
    public static readonly MyEnum D = new MyEnum( 4 );
    public static readonly MyEnum E = new MyEnum( 5 );

    protected MyEnum( int internalValue ) : base( internalValue )
    {
        // Nothing
    }
}

[TestMethod]
public void EnumTest()
{
    this.DoSomethingMeaningful( MyEnum.A );
}

private void DoSomethingMeaningful( MyBaseEnum enumValue )
{
    // ...
    if( enumValue == MyEnum.A ) { /* ... */ }
    else if (enumValue == MyEnum.B) { /* ... */ }
    // ...
}

기본이 예약된 단어라는 사실을 무시하면 열거형 상속을 수행할 수 없습니다.

당신이 할 수 있는 최선의 방법은 다음과 같은 것입니다.

public enum Baseenum
{
   x, y, z
}

public enum Consume
{
   x = Baseenum.x,
   y = Baseenum.y,
   z = Baseenum.z
}

public void Test()
{
   Baseenum a = Baseenum.x;
   Consume newA = (Consume) a;

   if ((Int32) a == (Int32) newA)
   {
   MessageBox.Show(newA.ToString());
   }
}

모두 동일한 기본 유형(즉, int)이므로 한 유형의 인스턴스에서 다른 유형의 인스턴스로 값을 할당할 수 있습니다.이상적이지는 않지만 효과가 있습니다.

이게 제가 한 일입니다. 한 이름을 사용하는 것입니다.new하는" "비에소"에 대한 enum의 이름 이후로.enum똑같아요, 그냥 아무 생각 없이 사용할 수 있고 맞을 거예요.게다가 지능도 얻을 수 있습니다.값이 기본값에서 복사되어 동기화된 상태로 유지되도록 설정할 때 수동으로 주의해야 합니다.코드 주석과 함께 도움이 될 수 있습니다.에 저장할 때 데이터베이스에 하는 또 입니다.enum값은 항상 값이 아니라 문자열을 저장합니다.자동으로 할당된 증가 정수 값을 사용하면 시간이 지남에 따라 변경될 수 있기 때문입니다.

// Base Class for balls 
public class Ball
{
    // keep synced with subclasses!
    public enum Sizes
    {
        Small,
        Medium,
        Large
    }
}

public class VolleyBall : Ball
{
    // keep synced with base class!
    public new enum Sizes
    {
        Small  = Ball.Sizes.Small,
        Medium = Ball.Sizes.Medium,
        Large  = Ball.Sizes.Large,
        SmallMedium,
        MediumLarge,
        Ginormous
    }
}

이 답변이 좀 늦었다는 것은 알지만 결국 이렇게 되었습니다.

public class BaseAnimal : IEquatable<BaseAnimal>
{
    public string Name { private set; get; }
    public int Value { private set; get; }

    public BaseAnimal(int value, String name)
    {
        this.Name = name;
        this.Value = value;
    }

    public override String ToString()
    {
        return Name;
    }

    public bool Equals(BaseAnimal other)
    {
        return other.Name == this.Name && other.Value == this.Value;
    }
}

public class AnimalType : BaseAnimal
{
    public static readonly BaseAnimal Invertebrate = new BaseAnimal(1, "Invertebrate");

    public static readonly BaseAnimal Amphibians = new BaseAnimal(2, "Amphibians");

    // etc        
}

public class DogType : AnimalType
{
    public static readonly BaseAnimal Golden_Retriever = new BaseAnimal(3, "Golden_Retriever");

    public static readonly BaseAnimal Great_Dane = new BaseAnimal(4, "Great_Dane");

    // etc        
}

그러면 다음과 같은 작업을 수행할 수 있습니다.

public void SomeMethod()
{
    var a = AnimalType.Amphibians;
    var b = AnimalType.Amphibians;

    if (a == b)
    {
        // should be equal
    }

    // call method as
    Foo(a);

    // using ifs
    if (a == AnimalType.Amphibians)
    {
    }
    else if (a == AnimalType.Invertebrate)
    {
    }
    else if (a == DogType.Golden_Retriever)
    {
    }
    // etc          
}

public void Foo(BaseAnimal typeOfAnimal)
{
}

대체 해결책

우리 회사에서는 일반적이지 않은 하위 수준의 프로젝트에 도달하기 위해 "프로젝트를 건너뛰는" 것을 피합니다.예를 들어, 프레젠테이션/API 계층은 도메인 계층만 참조할 수 있고 도메인 계층은 데이터 계층만 참조할 수 있습니다.

그러나 프레젠테이션 계층과 도메인 계층 모두에서 참조해야 하는 열거형이 있는 경우 이 문제가 발생합니다.

여기 우리가 (지금까지) 구현한 솔루션이 있습니다.그것은 꽤 좋은 해결책이고 우리에게 잘 작동합니다.다른 답들은 이 모든 것을 강타했습니다.

기본 전제는 열거형은 상속될 수 없지만 클래스는 상속될 수 있다는 것입니다.그래서...

// In the lower level project (or DLL)...
public abstract class BaseEnums
{
    public enum ImportanceType
    {
        None = 0,
        Success = 1,
        Warning = 2,
        Information = 3,
        Exclamation = 4
    }

    [Flags]
    public enum StatusType : Int32
    {
        None = 0,
        Pending = 1,
        Approved = 2,
        Canceled = 4,
        Accepted = (8 | Approved),
        Rejected = 16,
        Shipped = (32 | Accepted),
        Reconciled = (64 | Shipped)
    }

    public enum Conveyance
    {
        None = 0,
        Feet = 1,
        Automobile = 2,
        Bicycle = 3,
        Motorcycle = 4,
        TukTuk = 5,
        Horse = 6,
        Yak = 7,
        Segue = 8
    }

그런 다음 다른 상위 레벨 프로젝트에서 열거형을 "상속"하려면...

// Class in another project
public sealed class SubEnums: BaseEnums
{
   private SubEnums()
   {}
}

이것은 세 가지의 진정한 이점을 가지고 있습니다.

  1. 열거형 정의는 정의에 따라 두 프로젝트에서 자동으로 동일합니다.
  2. 열거형 정의에 대한 모든 변경 사항은 두 번째 클래스를 수정할 필요 없이 두 번째 클래스에서 자동으로 반향됩니다.
  3. 열거형은 동일한 코드를 기반으로 하므로 값을 몇 가지 주의 사항과 쉽게 비교할 수 있습니다.

번째 프로젝트의 열거형을 참조하려면 클래스의 접두사 BaseEnums를 사용합니다.상태 유형.고정 기본 열거형 사용을 보류 중이거나 사용에 "고정 기본 열거형 사용" 문을 추가합니다.

그러나 상속된 클래스를 처리할 때 번째 프로젝트에서는 "static ... 사용" 접근 방식을 사용할 수 없었기 때문에 "상속된 열거형"에 대한 모든 참조는 클래스(예: SubEnums)로 접두사가 붙습니다.상태 유형.보류 중.두 번째 프로젝트에서 "정적 사용" 접근법을 사용할 수 있는 방법을 생각해 낸 사람이 있으면 알려주십시오.

저는 이것이 훨씬 더 나아지도록 조정될 수 있다고 확신합니다. 하지만 이것은 실제로 효과가 있고 저는 작업 프로젝트에서 이 접근법을 사용했습니다.

저는 또한 에넘스를 과부하시키고 싶었고, 이 페이지의 '세븐'의 답변과 중복된 게시물에 '멀린 모건-그레이엄'의 답변혼합하여 만들었고, 몇 가지 개선 사항을 추가했습니다.
다른 솔루션에 비해 당사 솔루션의 주요 이점은 다음과 같습니다.

  • 기본 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
}

제가 이 파티에 좀 늦었다는 것은 알지만, 여기 제 2센트입니다.

Enum 상속이 프레임워크에서 지원되지 않는다는 것은 확실합니다.이 스레드에서 몇 가지 매우 흥미로운 해결 방법이 제안되었지만, 그 중 어느 것도 제가 찾고 있는 것과 같지 않아 직접 시도해 보았습니다.

소개:개체 열거

코드 및 설명서는 https://github.com/dimi3tron/ObjectEnum 에서 확인할 수 있습니다.

그리고 여기 패키지: https://www.nuget.org/packages/ObjectEnum

하세요: 또는설하됩니다.Install-Package ObjectEnum

대컨요,ObjectEnum<TEnum>모든 열거형의 래퍼 역할을 합니다.하위 클래스에서 GetDefinedValues()를 재정의하여 이 특정 클래스에 유효한 열거 값을 지정할 수 있습니다.

여러 연산자 오버로드가 추가되어 다음을 수행할 수 있습니다.ObjectEnum<TEnum>인스턴스는 정의된 값 제한을 염두에 두고 기본 열거형의 인스턴스처럼 동작합니다.즉, 인스턴스를 int 또는 enum 값과 쉽게 비교하여 스위치 케이스 또는 다른 조건부로 사용할 수 있습니다.

위에서 언급한 github repo를 참고하여 예시와 추가 정보를 얻고 싶습니다.

이것이 도움이 되길 바랍니다.더 많은 생각이나 의견을 위해 자유롭게 의견을 말하거나 github에서 이슈를 열어보세요.

▁you다▁with▁do예▁here▁of로 할 수 있는 몇 예를 .ObjectEnum<TEnum>:

var sunday = new WorkDay(DayOfWeek.Sunday); //throws exception
var monday = new WorkDay(DayOfWeek.Monday); //works fine
var label = $"{monday} is day {(int)monday}." //produces: "Monday is day 1."
var mondayIsAlwaysMonday = monday == DayOfWeek.Monday; //true, sorry...

var friday = new WorkDay(DayOfWeek.Friday);

switch((DayOfWeek)friday){
    case DayOfWeek.Monday:
        //do something monday related
        break;
        /*...*/
    case DayOfWeek.Friday:
        //do something friday related
        break;
}

열거형은 실제 클래스가 아닙니다. 겉으로 보기에 그렇다 하더라도 말입니다.내부적으로는 기본 유형(기본값 Int32)과 동일하게 처리됩니다.따라서 한 열거형에서 다른 열거형으로 단일 값을 "복사"하고 정수 값에 캐스팅하여 동일성을 비교해야 합니다.

열거형은 다른 열거형에서 파생될 수 없으며 int, int, short, usshort, long, ulong, 바이트 및 sbyte에서만 파생됩니다.

파스칼이 말한 것처럼 다른 열거형의 값이나 상수를 사용하여 열거형 값을 초기화할 수 있지만, 그 정도입니다.

다른 가능한 해결책:

public enum @base
{
    x,
    y,
    z
}

public enum consume
{
    x = @base.x,
    y = @base.y,
    z = @base.z,

    a,b,c
}

// TODO: Add a unit-test to check that if @base and consume are aligned

HTH

(@JaredPar가 이미 언급했듯이) 이것은 불가능합니다.이 문제를 해결하기 위해 논리를 사용하는 것은 나쁜 관행입니다.당신이 가지고 있는 경우.base class그것을 가지고 있는enum은 가능한 것을 .enum-values거기서, 그리고 수업의 구현은 그것이 알고 있는 가치들과 함께 작동해야 합니다.

클래스 예: 기본클있다가정합니다고가스래▁a▁class다▁you▁e▁base▁have:니가합예정있▁supposed다.BaseCatalog 리고그 가 있습니다.enum ProductFormats(Digital,Physical. 그러면 당신은 가질 수 있습니다.MusicCatalog또는BookCatalog 다 도 있습니다.Digital그리고.Physical제품, 하지만 수업이ClothingCatalog▁contains다만 포함되어야 .Physical상품들.

이 작업을 수행하는 방법은 상속된 열거형 개념에서 원하는 기능을 포함하는 고유한 클래스 구조를 구현하고 추가할 수 있습니다.단순히 코드화하는 값을 찾기 위해 동등한 비교기와 함수를 구현합니다.생성자를 비공개로 설정하고 원하는 범위 내에서 클래스와 하위 클래스의 정적 인스턴스를 선언합니다.또는 문제에 대한 간단한 해결 방법을 찾아 기본 열거형 구현을 수행합니다.

상속된 열거의 코드가 많은 구현:

/// <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;

}

하위 클래스에는 별도의 열거형이 필요하지만 ID로 int 대신 열거형을 사용할 수 있습니다.열거형 클래스 자체는 모든 종류의 플래그, 메시지, 기능 등으로 장식될 수 있습니다.일반적인 구현은 코드의 상당 부분을 줄일 수 있습니다.

상황에 따라 파생된 열거형이 기반이므로 필요하지 않을 수 있습니다.System.Enum.

이 코드를 사용하여 원하는 Enum을 전달하고 선택한 값을 얻을 수 있습니다.

public CommonError FromErrorCode(Enum code)
{
    Code = (int)Enum.Parse(code.GetType(), code.ToString());

열거형에서 상속을 수행할 수 있지만 다음 유형으로만 제한됩니다. int, uint, 바이트, 바이트, sbyte, short, usshort, long, ullong

예.

public enum Car:int{
Toyota,
Benz,
}

언급URL : https://stackoverflow.com/questions/757684/enum-inheritance

반응형