C# узнать, определена ли переменная в модели

В настоящее время я разрабатываю приложение 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»

Большое спасибо за ваше время.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если у вас есть только эти три переменные, я рекомендую добавить коллекцию, содержащую имена переменных:

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

Я бы сделал вызов отражения только один раз, при инициализации класса. Поэтому мы не повторяем операцию отражения снова и снова, а только один раз.

Michał Turczyn 12.03.2024 09:15
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 в список строк, содержащий имена полей.

Другие вопросы по теме