인터페이스/기본 클래스의 C# Enum?
문제
나는 Enum에 문제가 있습니다
기본 클래스 또는 인터페이스에서 열거를 만들 필요가 있습니다 (그러나 비어있는 것).
class Base
{
public enum Test;
// ???
}
그리고 일부 부모 수업에서 다른 열거를 만든 후
class Parent1
{
public enum Test {A, B, C};
}
class Parent2
{
public enum Test {J, H, K};
}
그리고 이제 나는 Enum을 사용해야 할 때 방법이있는 다음 수업을 가지고 있습니다.
class Test<T>
{
public void Foo(Test enum)
{
int value = (int) enum;
// ...
}
}
그런 일을 할 수있는 방법이 있습니까?
그렇지 않다면 모든 클래스에서 정적 INT를 사용해야합니다 ...
class Parent1
{
public static int A = 0;
public static int B = 5;
public static int C = 7;
}
class Parent2
{
public static int J = 1;
public static int H = 3;
public static int K = 6;
}
class Test<T>
{
public void Foo(int enum)
{
int value = enum;
// ...
}
}
코드에서 나쁘지 않은 것 같습니다 ... 일부 클래스에서는 ~ 20+ 변수를 사용해야합니다.
해결책
초록 열거 (서브 클래스에서 다른 구현을 가질 수 있음)와 같은 것은 없지만 제네릭은 옵션 일 수 있습니다.
class Base<T> where T : struct {
private T value;
public void Foo(T value) {
this.value = value;
}
}
class Parent1 : Base<Parent1.Enum1> {
public enum Enum1 {A, B, C};
}
class Parent2 : Base<Parent2.Enum2> {
public enum Enum2 { J, H, K };
}
유일한 문제는 이것이 열거 만 사용할 수 있음을 시행하지 않는다는 것입니다. 예를 들어 유형 이니셜 라이저에서 런타임에이를 수행 할 수 있습니다.
static Base() {
if (!typeof(T).IsEnum) throw new InvalidOperationException(
typeof(T).Name + " is not an enum");
}
다른 팁
사람들이 논쟁하는 사람을 얼마나 자주 찾는 지 놀랍습니다. 왜 질문에 대답하거나 Schtum을 유지하기보다는 무언가가 필요합니다. 왜 응답자가 실제로 답변을 알고있는 다른 조사를 선호하는 주어진 조사가 이루어졌습니다. 묻지 않은 질문에 대답하는 것은 도움이되지 않습니다.
당면한 주제로 돌아가서, 나는 오늘 아침 위의 시나리오를 정확히 누르고 있으며, 인터페이스 나 기본 클래스에서 열거를 정의 할 수있는 것이 유용한 이유를 이해하고 동일한 이름이 열거를 다시 정의하십시오. 베이스 또는 인터페이스에서 파생되는 클래스에서. 이러한 설계에 대한 하나의 용도는 객체 관계 매핑 및 제어 바인딩에 있습니다. 파생 클래스의 어떤 속성이 어떤 유형의 제어 유형에 따라 다음과 같은 어떤 유형의 열거가있을 수 있습니다.
public enum WebControlTextBoxProperties { }
public enum WebControlLabelProperties { }
...등등.
관련 상속이 적용 될 때까지 주어진 파생 클래스에 어떤 속성이 존재할 것인지 정확히 알지 못하므로 기본 또는 인터페이스에서 위의 열거를 소비하는 일관된 방법을 원하기 때문에 완벽하게 밸리에도 디자인입니다. 열거 존재할 것입니다 베이스/인터페이스에서는 정확히 정의합니다 어떤 회원 그것은 모든 파생 클래스에서 특정 맥락에 있습니다.
VB에서와 같이 C#에서 이것이 가능하기를 정말로 원합니다. 왜냐하면 그것이 정말 유용한 기능이기 때문입니다.
기본 클래스에서 열거를 선언 한 다음 파생 된 클래스 당 값을 변경할 수 있어야합니다.
class MyClass
{
public enum TestEnum { }
public MyClass()
{
}
}
class MyDerivedClass
{
public enum TestEnum { value1, value2, value3 }
public MyDerivedClass()
{
}
}
MyDervied 클래스는 testenum.value1, testenum.value2, testenum.value3에 액세스 할 수 있습니다. 여기서 myclass는 유형에만 액세스 할 수 있습니다.
그러나 개인적으로 나는 이것을하는 이점을 보지 못합니다. 나는 기본 클래스에서 열거의 모든 값을 선언하고 수업 당 필요한 것만 사용합니다.
제임스.
아니요, 할 수 없습니다.
많은 열거는 종종 설계 문제를 나타냅니다 (예 : 많은 스위치 구조물). 이 링크를 확인하려면 다음과 같은 정보를 확인하십시오. 조건부를 다형성으로 대체하십시오.
아니요, 인터페이스에서 정적을 시행 할 방법이 없습니다.
아마도 당신은 당신의 디자인을 다시 생각해야 할 것입니다.
기본 클래스에서 열거를 정의 할 수없는 이유 :
class Base
{
public enum Test {A, B, C, J, H, K};
}
그리고 파생 클래스에서 Enum의 관련 멤버 만 사용합니까?
나는 일하고 있으므로 완전히 정교 할 수는 없지만 이것은 어느 정도 가능합니다. 아래 코드의 단점은 TextBoxProperties 및 MyCustomTextBoxProperties와 같은 Enums를 함께 체인 할 수 없다는 것입니다 : TextBoxProperties
코드는 다음과 같습니다.
public enum Test
{
}
public enum ThisTest
{
MyVal1,
MyVal2,
MyVal3
}
public abstract class MyBase
{
public Test MyEnum { get; set; }
}
public class MyDerived : MyBase
{
public new ThisTest MyEnum { get; set; }
}
너 할 수 있다 열거적!
사람들이 왜 아무것도 확인하지 않고 물건을 불가능하다고 주장하는 이유는 무엇입니까?
물론 .NET 문서는 이것에 대해 약간 모호하지만 System.enum 클래스는 열거의 추상화입니다. System.enum을 열거 값 만 수락하는 변수로 사용할 수 있으며이 클래스를 통해 열거의 이름 또는 값 유형 값에 액세스 할 수 있습니다.
예를 들어:
// abstracted enumeration value
Enum abstractEnum = null;
// set to the Console-Color enumeration value "Blue";
abstractEnum = System.ConsoleColor.Blue;
// the defined value of "ConsoleColor.Blue" is "9":
// you can get the value via the ToObject method:
Console.WriteLine((int)Enum.ToObject(abstractEnum.GetType(), abstractEnum));
// or via the GetHashCode() method:
Console.WriteLine(abstractEnum.GetHashCode());
// the name can also be acessed:
Console.WriteLine(Enum.GetName(abstractEnum.GetType(), abstractEnum));
위 코드의 출력 :
9
9
푸른
나는 @Marc Gravell의 받아 들여진 대답을 좋아합니다. 나는 stackoverflow-newbie이므로 댓글을 달 수 없습니다. 그러나 기본 유형의 열거 유형을 확인하는 것이 유용하다고 추가하고 싶습니다. 특히 플래그 속성을 사용하고 비트 와이즈 프레임 테스트 작업을 미리 형태로 사용하는 경우 ...
if ( !typeof(T).IsEnum || typeof(int) != Enum.GetUnderlyingType(typeof(T)) )
{
throw new InvalidOperationException( typeof(T).Name + " is not an enum");
}
다음은 저에게 적합한 솔루션입니다.
상위 클래스에서는 필드를 열거가 아닌 int로 선언합니다.
protected int state;
따라서 부모 클래스는이 값을 디스크에 직렬화 및 사로화하기 위해이 값을 INT로 사용할 수 있습니다.
그런 다음 수업을 무시하는 사람은 다음을 수행 할 수 있습니다.
enum states{
state1, state2
}
this.state = state1.toInt();
다음과 같은 실제 값에 액세스 할 수 있습니다.
...
if (this.state == states.state1.toInt()){
...
}
else{
...
}
Toint ()가 다음과 같이 정적 클래스에 정의 된 위치.
public static class Utils
{
public static int toInt(this state s)
{
return (int)s;
}
}