Enum 값이 같으면 어떤 Enum 상수를 얻을 수 있습니까?
동일한 값을 가진 열거 형 상수가 두 개 이상있는 경우 어떤 상수에 대한 논리가 있습니까?
아래 변형을 시도했지만 합리적인 논리를 얻지 못했습니다.
주요 방법 :
public class Program
{
public static void Main(string[] args)
{
Test a = 0;
Console.WriteLine(a);
}
}
첫 시도:
enum Test
{
a1=0,
a2=0,
a3=0,
a4=0,
}
산출:
a2
두 번째 시도 :
enum Test
{
a1=0,
a2=0,
a3,
a4=0,
}
산출:
a4
세 번째 시도 :
enum Test
{
a1=0,
a2=0,
a3,
a4,
}
산출:
a2
네 번째 시도 :
enum Test
{
a1=0,
a2=0,
a3,
a4
}
산출:
a1
문서는 실제로 주소 :
여러 열거 형 멤버에 동일한 기본 값이 있고 기본 값을 기반으로 열거 형 멤버 이름의 문자열 표현을 검색하려는 경우 코드에서 메서드가 반환 할 이름에 대해 가정하지 않아야합니다 .
(강조 추가됨)
그러나 이것이 결과가 무작위 임을 의미하지는 않습니다 . 이것이 의미 하는 바는 변경 될 수있는 구현 세부 사항이라는 것입니다 . 구현은 패치만으로 완전히 변경 될 수 있으며 컴파일러 (MONO, Roslyn 등)에 따라 다를 수 있으며 플랫폼마다 다를 수 있습니다.
시스템이이 있도록 설계되어있는 경우 필요 열거 형에 대한 역방향 조회 시간과 플랫폼에 걸쳐 일관성이 있음을, 다음 사용하지 마십시오 Enum.ToString
. 하나는 그 세부에 의존하지 그래서 설계를 변경하거나 쓰기 자신의 방법 것입니다 일치합니다.
따라서 해당 구현에 의존하는 코드를 작성하지 마십시오. 그렇지 않으면 향후 릴리스에서 사용자 모르게 변경 될 위험을 감수해야합니다.
TL; DR : 열거 형의 모든 필드는 리플렉션에 의해 추출 된 다음 삽입 정렬 및 이진 검색에서 첫 번째 일치 값을 찾습니다.
콜 체인은 다음과 같습니다.
Enum.Tostring();
Enum.InternalFormat(RuntimeType eT, Object value);
Enum.GetName(Type enumType, Object value);
Type.GetEnumName(object value);
Type.GetEnumName(object value)
다음과 같이 구현됩니다.
public virtual string GetEnumName(object value)
{
// standard argument guards...
Array values = GetEnumRawConstantValues();
int index = BinarySearch(values, value);
if (index >= 0)
{
string[] names = GetEnumNames();
return names[index];
}
return null;
}
둘 다 GetEnumRawConstantValues()
및 GetEnumNames()
의존 GetEnumData(out string[] enumNames, out Array enumValues)
:
private void GetEnumData(out string[] enumNames, out Array enumValues)
{
Contract.Ensures(Contract.ValueAtReturn<String[]>(out enumNames) != null);
Contract.Ensures(Contract.ValueAtReturn<Array>(out enumValues) != null);
FieldInfo[] flds = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
object[] values = new object[flds.Length];
string[] names = new string[flds.Length];
for (int i = 0; i < flds.Length; i++)
{
names[i] = flds[i].Name;
values[i] = flds[i].GetRawConstantValue();
}
// Insertion Sort these values in ascending order.
// We use this O(n^2) algorithm, but it turns out that most of the time the elements are already in sorted order and
// the common case performance will be faster than quick sorting this.
IComparer comparer = Comparer.Default;
for (int i = 1; i < values.Length; i++)
{
int j = i;
string tempStr = names[i];
object val = values[i];
bool exchanged = false;
// Since the elements are sorted we only need to do one comparision, we keep the check for j inside the loop.
while (comparer.Compare(values[j - 1], val) > 0)
{
names[j] = names[j - 1];
values[j] = values[j - 1];
j--;
exchanged = true;
if (j == 0)
break;
}
if (exchanged)
{
names[j] = tempStr;
values[j] = val;
}
}
enumNames = names;
enumValues = values;
}
, 다음 경우 GetFields(BindingFlags bindingAttr)
에 리드 abstract
방법을하지만, MSDN에 "GetFields"를 검색하면을 얻을 것입니다 EnumBuilder.GetFields(BindingFlags bindingAttr)
. 그리고 콜 체인을 따라 간다면 :
EnumBuilder.GetFields(BindingFlags bindingAttr);
TypeBuilder.GetFields(BindingFlags bindingAttr);
RuntimeType.GetFields(BindingFlags bindingAttr);
RuntimeType.GetFieldCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup);
RuntimeTypeCache.GetFieldList(MemberListType listType, string name);
RuntimeTypeCache.GetMemberList<RuntimeFieldInfo>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType);
MemberInfoCache<RuntimeFieldInfo>.GetMemberList(MemberListType listType, string name, CacheType cacheType);
MemberInfoCache<RuntimeFieldInfo>.Populate(string name, MemberListType listType, CacheType cacheType);
MemberInfoCache<RuntimeFieldInfo>.GetListByName(char* pName, int cNameLen, byte* pUtf8Name, int cUtf8Name, MemberListType listType, CacheType cacheType);
MemberInfoCache<RuntimeFieldInfo>.PopulateFields(Filter filter);
// and from here, it is a wild ride...
그래서 Type.GetFields
비고 를 인용하겠습니다 .
GetFields 메서드는 알파벳순 또는 선언 순서와 같은 특정 순서로 필드를 반환하지 않습니다. 필드가 반환되는 순서가 다르기 때문에 코드는 필드가 반환되는 순서에 의존해서는 안됩니다.
'code' 카테고리의 다른 글
각도기에서 browser.ignoreSynchronization은 무엇입니까? (0) | 2020.12.12 |
---|---|
전자에서 DOM 요소에 액세스하는 방법은 무엇입니까? (0) | 2020.12.12 |
OpenAI에서 새로운 체육관 환경을 만드는 방법은 무엇입니까? (0) | 2020.12.12 |
Xcode 10.2가 iOS 10 미만의 시뮬레이터에서 앱을 실행하지 못했습니다. (0) | 2020.12.12 |
포트 80 및 443에 대한 Virtualhost 지시문을 복제해야합니까? (0) | 2020.12.12 |