#c# #enums
#c# #перечисления
Вопрос:
public EnumA
{
name = 1,
surname = 2
}
public EnumB
{
name = 50,
surname = 60
}
public void myMethod(User u,Enum e)
{
//Enum e can be either EnumA or EnumB
//Do something with the Enum Passed
}
Допустим, у меня есть приведенный выше код, но вместо указания перечисления в методе, как я делаю выше, я хотел бы выбрать перечисление, которое передается через параметр метода. Есть ли какой-либо способ сделать это?
Комментарии:
1. Можете ли вы привести больше примеров того, какой результат вы хотели бы видеть, и как вы вызываете
myMethod
? Я пока не понимаю, чего вы пытаетесь достичь.2. @BradleyUffner В соответствии с которым передается Enum, я хочу получить все значения Enum
3. Все ли ваши перечисления имеют
name
surname
элементы и?4. Почему у вас есть два перечисления, содержащие одну и ту же информацию? Кроме того, есть ли у вас реальный пример того, чего вы пытаетесь достичь, чтобы мы могли оказать вам наилучшую помощь
Ответ №1:
Вы можете сделать это с помощью отражения, но я беспокоюсь, что вы неправильно понимаете перечисления. Мне кажется, что вы пытаетесь использовать их как экземпляры класса для хранения произвольных данных, и в этом случае вам действительно следует использовать real class
.
На случай, если я ошибаюсь, я включил ниже код, чтобы сделать то, что вы просите, но я не думаю, что это будет очень полезно для вас.
void Main()
{
Test(EnumA.First);
Console.WriteLine("-----");
Test(EnumB.B);
}
void Test(Enum theEnum)
{
Type t = theEnum.GetType();
foreach (string element in Enum.GetNames(t))
{
Debug.WriteLine(element " = " (int) Enum.Parse(t, element));
}
}
enum EnumA
{
First = 1,
Second = 2
}
enum EnumB
{
A = 1,
B = 2,
C = 3
}
Он генерирует следующий вывод:
First = 1
Second = 2
-----
A = 1
B = 2
C = 3
Я думаю, что это больше то, что вы пытаетесь сделать, хотя:
void Main()
{
Person A = new Person()
{
Name = "John",
Surname = "Doe"
};
Person B = new Person()
{
Name = "Jane",
Surname = "Doe"
};
A.ShowInfo();
Console.WriteLine("----");
B.ShowInfo();
}
class Person
{
public string Name { get; set; }
public string Surname { get; set; }
public void ShowInfo()
{
Debug.WriteLine("Name=" Name);
Debug.WriteLine("Surname=" Surname);
}
}
Он выводит следующее:
Name=John
Surname=Doe
----
Name=Jane
Surname=Doe
Ответ №2:
Вы пробовали следующее:
public void myMethod(User u,Enum e)
{
if (e is EnumA)
{
EnumA ea = (EnumA)e;
// Do something with ea
}
else if (e is EnumB)
{
EnumB eb = (EnumB)e;
...
}
}
Комментарии:
1. Это сработало бы, но что, если бы у меня было слишком много перечислений (что непрактично, но это решение, над которым я работаю)
2. Если у вас было так много перечислений, то вы делаете это неправильно. Я даже не вижу причины для перечисления, которое вы указали в своем примере. Вы знаете, что существуют перечисления «флагов»?
Ответ №3:
для этой операции вы должны использовать универсальный тип.
ниже приведен пример кода (в виде консольного приложения);
class Program
{
static void Main(string[] args)
{
myMethod<EnumA>("deneme", EnumA.name);
}
public enum EnumA
{
name = 1,
surname = 2
}
public enum EnumB
{
name = 50,
surname = 60
}
public static void myMethod<T>(string u, T e)
where T : struct,IConvertible
{
if (typeof(T) == typeof(EnumA))
{
Console.WriteLine("EnumA");
}
else if (typeof(T) == typeof(EnumB))
{
Console.WriteLine("EnumB");
}
Console.ReadLine();
}
}
Ответ №4:
Вы могли бы использовать перегрузку:
public void myMethod(User u, EnumA e)
{
// Call a function common to both
}
public void myMethod(User u, EnumB e)
{
// Call a function common to both
}
Я думаю, C # 7.3 позволяет вам делать что-то вроде:
public void myMethod(User u, TEnum e) where TEnum : Enum
{
//Enum e can be either EnumA or EnumB
//Do something with the Enum Passed
}
Я использовал что-то подобное для проекта до версии 7.3, и это было немного некрасиво, но намного лучше и удобочитаемее, чем любой другой способ, который я мог найти:
public void myMethod(User u, object e)
{
// Test to make sure object type is either EnumA or EnumB
// Call a function common to both
// object e can be either EnumA or EnumB by casting like ((EnumA)e) or ((EnumB)e)
}
Ответ №5:
Перечисления ведут себя (или должны вести себя) не так. По сути, вы создаете два разных экземпляра enums . Вот почему классы существуют в C #. Подумайте о создании класса:
public class SomeEnum
{
public int Name;
public int Surname;
private SomeEnum(int name, int surname)
{
Name = name;
Surname = surname;
}
public static SomeEnum EnumA => new SomeEnum(1, 2);
public static SomeEnum EnumB => new SomeEnum(50, 60);
}
И измените свой метод на этот:
public void myMethod(User u, SomeEnum e)
{
// Enum e can be either EnumA or EnumB
// Do something with the Enum passed
}
Я изменил как можно меньше кода, поскольку я не уверен, какова цель этих «перечислений», но таким образом вы сможете создавать столько экземпляров, сколько захотите, без того, чтобы ваш код запутался со всеми этими идентичными спецификациями перечисления.
Чтобы использовать этот метод с EnumA, например, вы можете вызвать myMethod(user, SomeEnum.EnumA)
.
Таким образом, можно использовать только указанные перечисления ( EnumA
и EnumB
). В качестве альтернативы, если вы хотите создавать перечисления «на лету», код можно изменить на:
public class SomeEnum
{
public int Name;
public int Surname;
public SomeEnum(int name, int surname)
{
Name = name;
Surname = surname;
}
}
Таким образом, вы можете вызвать метод с myMethod(user, new SomeEnum(1, 2))
помощью .