저수준 네임 스페이스에 열거 형이 있습니다. 저수준 열거 형을 “상속”하는 중간 수준 네임 스페이스에 클래스 또는 열거 형을 제공하고 싶습니다.
namespace low
{
public enum base
{
x, y, z
}
}
namespace mid
{
public enum consume : low.base
{
}
}
나는 이것이 가능하거나 열거 형 소비를 대체 할 수있는 일종의 클래스가 있기를 바라고 있습니다.
생각?
편집 : 클래스에서 const로 전환하지 않은 이유 중 하나는 내가 사용해야하는 서비스에 저수준 열거가 필요하기 때문입니다. 구조를 열거 형으로 정의하는 WSDL과 XSD를 받았습니다. 서비스를 변경할 수 없습니다.
답변
이건 불가능 해. 열거 형은 다른 열거 형에서 상속 할 수 없습니다. 실제로 모든 열거 형은 실제로에서 상속해야합니다 System.Enum
. C #에서는 구문이 상속처럼 보이는 열거 형 값의 기본 표현을 변경할 수 있지만 실제로는 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;
업데이트 (질문 업데이트 후) :
기존 열거 형에 정의 된 것과 동일한 정수 값을 상수에 할당하면 열거 형과 상수 사이에 캐스트 할 수 있습니다. 예를 들면 다음과 같습니다.
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
}
그러나 Base.A! = Consume.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);
}
}
Base와 Consume을 교차하려면 …
열거 형의 값을 정수로 캐스팅하고 열거 형 대신 정수로 비교할 수도 있지만 그러한 종류의 짜증도 있습니다.
확장 메소드 리턴은 유형 T를 캐스트해야합니다.
답변
정수 상수가있는 클래스를 사용하는 위의 솔루션에는 형식 안전성이 없습니다. 즉, 클래스에 실제로 정의되지 않은 새로운 값을 발명 할 수 있습니다. 또한 예를 들어 이러한 클래스 중 하나를 입력으로 사용하는 메소드를 작성할 수 없습니다.
당신은 쓸 필요가있을 것입니다
public void DoSomethingMeaningFull(int consumeValue) ...
그러나 사용 가능한 열거 형이 없었던 Java의 클래스 기반 솔루션이 있습니다. 이것은 거의 열거 같은 행동을 제공합니다. 유일한 경고는 이러한 상수를 switch 문 내에서 사용할 수 없다는 것입니다.
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) { /* ... */ }
// ...
}
답변
base가 예약어라는 사실을 무시하면 enum의 상속을 수행 할 수 없습니다.
가장 좋은 방법은 다음과 같습니다.
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)이기 때문에 한 타입의 인스턴스에서 다른 타입으로 캐스팅 된 값을 할당 할 수 있습니다. 이상적이지는 않지만 작동합니다.
답변
나는이 답변이 늦다는 것을 알고 있지만 이것이 내가 한 일입니다.
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)
{
}
답변
이것이 내가 한 일입니다. 내가 다르게 한 것은 new
“소비”에 동일한 이름과 키워드를 사용하는 것 enum
입니다. 의 이름이 enum
동일하기 때문에 마음대로 사용할 수 있으며 옳습니다. 게다가 당신은 지능을 얻습니다. 값을 기준에서 복사하여 동기화되도록 설정할 때 수동으로주의해야합니다. 코드 주석과 함께 도움이 될 수 있습니다. 이것이 데이터베이스에서 enum
값을 저장할 때 항상 값이 아닌 문자열을 저장하는 또 다른 이유 입니다. 자동으로 할당 된 증가하는 정수 값을 사용하는 경우 시간이 지남에 따라 변경 될 수 있습니다.
// Base Class for balls
public class BaseBall
{
// keep synced with subclasses!
public enum Sizes
{
Small,
Medium,
Large
}
}
public class VolleyBall : BaseBall
{
// keep synced with base class!
public new enum Sizes
{
Small = BaseBall.Sizes.Small,
Medium = BaseBall.Sizes.Medium,
Large = BaseBall.Sizes.Large,
SmallMedium,
MediumLarge,
Ginormous
}
}
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)