В настоящее время я разрабатываю приложение MVVM и застрял, пытаясь найти выход из этой ситуации. Итак, у меня есть модель, построенная как таковая:
public class Variables
{
/* Elementary variables */
public static readonly UInt16 Var1 = 1;
public static readonly UInt16 Var2 = 2;
public static readonly UInt16 Var3 = 3;
}
Я хочу в viewModel проверить, действительно ли строка, полученная из пользовательского ввода, которая должна соответствовать Var1, Var2 или Var3 (имя переменной, а не ее значение), действительно соответствует.
Что-то вроде
if (UserInput.Name in VariablesName){ }
Где имя переменной будет списком переменных переменных. например, это было бы верно, если бы пользователь ввел «Var1»
Большое спасибо за ваше время.





Если у вас есть только эти три переменные, я рекомендую добавить коллекцию, содержащую имена переменных:
public class Variables
{
/* Elementary variables */
public static readonly UInt16 Var1 = 1;
public static readonly UInt16 Var2 = 2;
public static readonly UInt16 Var3 = 3;
public static IEnumerable<string> VariableNames { get; } = new string[] { nameof(Var1), nameof(Var2), nameof(Var3) };
}
Однако если вы часто добавляете или удаляете переменные, это может быть не лучшим решением, поскольку вам придется каждый раз помнить о том, что нужно также добавлять или удалять элемент из коллекции. В этом случае вы можете использовать отражение:
public class Variables
{
/* Elementary variables */
public static readonly UInt16 Var1 = 1;
public static readonly UInt16 Var2 = 2;
public static readonly UInt16 Var3 = 3;
public static IEnumerable<string> VariableNames
{
get
{
return typeof(Variables).GetFields(BindingFlags.Static | BindingFlags.Public).Select(x => x.Name);
}
}
}
Вы должны знать, что отражение происходит довольно медленно. Если вам нужна высокая производительность, это не лучшее решение. Вы можете немного повысить производительность, если будете выполнять код отражения только один раз, а не при каждом вызове метода получения свойства:
public class Variables
{
/* Elementary variables */
public static readonly UInt16 Var1 = 1;
public static readonly UInt16 Var2 = 2;
public static readonly UInt16 Var3 = 3;
public static IEnumerable<string> VariableNames { get; } = typeof(Variables).GetFields(BindingFlags.Static | BindingFlags.Public).Select(x => x.Name).ToArray();
}
Онлайн-демо: https://dotnetfiddle.net/mWc6AP
using System;
using System.Collections.Generic;
using System.Reflection;
public class Program
{
public static void Main()
{
new ViewModel().CheckVariable("Var1");
new ViewModel().CheckVariable("Var4");
}
}
public class Variables
{
/* Elementary variables */
public static readonly UInt16 Var1 = 1;
public static readonly UInt16 Var2 = 2;
public static readonly UInt16 Var3 = 3;
}
public class ViewModel
{
public void CheckVariable(string userInput)
{
// Get all static fields of the Variables class
FieldInfo[] fields = typeof(Variables).GetFields(BindingFlags.Static | BindingFlags.Public);
// Convert the fields array to a list of their names
var fieldNames = new List<string>();
foreach (var field in fields)
{
fieldNames.Add(field.Name);
}
// Check if the userInput matches any of the field names
if (fieldNames.Contains(userInput))
{
Console.WriteLine($"{userInput} is a valid variable name.");
}
else
{
Console.WriteLine($"{userInput} is not a valid variable name.");
}
}
}
Метод ViewModel.CheckVariable получает все статические поля класса Variables, используя typeof(Variables).GetFields(BindingFlags.Static | BindingFlags.Public). Затем он преобразует этот массив объектов FieldInfo в список строк, содержащий имена полей.
Я бы сделал вызов отражения только один раз, при инициализации класса. Поэтому мы не повторяем операцию отражения снова и снова, а только один раз.