Хобрук: Ваш путь к мастерству в программировании

Как правильно получить доступ к общедоступному свойству UserControl по строке

У меня есть набор пользовательских элементов управления на странице, которые динамически загружаются в зависимости от состояния для запуска различных отчетов (драйвер условия). Каждый элемент управления имеет одно или несколько открытых свойств, которые будут использоваться для получения данных из моего запроса к базе данных. Поскольку элементы управления различаются для каждого отчета, я написал процедуру для доступа к соответствующему свойству элемента управления по имени, чтобы я мог отправить его в запрос к базе данных в коде (C#). Я настроил все для доступа к общедоступному свойству следующим образом:

stringVal = userControl.Attributes[stringName].ToString();

и он говорит мне, что мне нужно обновить объект. Я не понимаю, как мне нужно динамически обращаться к этому свойству по имени строки. В моем непосредственном окне я вижу свойство, которое хочу; но это не "Атрибут", как control.Attributes.Count = 0. Итак, как мне правильно настроить это, чтобы я мог получить к нему доступ по имени строки? Нужно ли чем-то украшать недвижимость?

Заранее спасибо.

01.02.2012

  • new up означает, что вы создадите новый экземпляр этого пользовательского элемента управления. например UserControl usrCtrl = новый UserControl 01.02.2012
  • Использование отражения, как кажется, не лучший способ. Если вы знаете, что захотите запросить у каждого из этих различных типов элементов управления их Name, например, просто создайте абстракцию, которая имеет и реализует это свойство, а затем извлеките из него элементы управления. 01.02.2012

Ответы:


1

Ниже я написал класс-оболочку, который вы можете использовать для установки/получения общедоступных полей или свойств класса-оболочки по строковому имени.

Во-первых, давайте посмотрим, как вы можете использовать его в классе с общедоступными полями или свойствами StartDate и SocialSecurityNumber.

// First create the instance we'll want to play with
MyUserControl myControlInstance = new MyUsercontrol();
// MyUserContol has two properties we'll be using
// DateTime StartDate
// int SocialSecurityNumber

// Now we're creating a map to facilitate access to the properties
// of "myControlInstance" using strings
PropertyMap<MyUserControl> map = 
             new PropertyMap<MyUserControl>(myControlInstance);

// Since the map is directed toward "myControlInstance"
// this line is equivalent to:
// myControlInstance.StartDate = Datetime.Now;
map.Set<DateTime>("StartDate", DateTime.Now);

// This line is equivalent to:
// ssn = myUsercontrol.SocialSecurityNumber;
int ssn = map.Get<int>("SocialSecurityNumber");

А теперь о том, как это реализовано:

public class PropertyMap<T>
{
    readonly T Instance;

    public PropertyMap(T instance)
    {
        Instance = instance;
    }

    public U Get<U>(string PropertyName)
    {
        // Search through the type's properties for one with this name
        // Properties are things with get/set accessors
        PropertyInfo property = typeof(T).GetProperty(PropertyName);
        if (property == null)
        {
            // if we couldn't find a property, look for a field.
            // Fields are just member variables, but you can only
            // manipulate public ones like this.
            FieldInfo field = typeof(T).GetField(PropertyName);
            if (field == null)
                throw new Exception("Couldn't find a property/field named " + PropertyName);
            return (U)field.GetValue(Instance);
        }
        return (U)property.GetValue(Instance, null);
    }

    public void Set<U>(string PropertyName, U value)
    {
        // Search through the type's properties for one with this name
        PropertyInfo property = typeof(T).GetProperty(PropertyName);
        if (property == null)
        {
            // if we couldn't find a property, look for a field.
            FieldInfo field = typeof(T).GetField(PropertyName);
            if (field == null)
                throw new Exception("Couldn't find a property/field named " + PropertyName);
            field.SetValue(Instance, value);
            return;
        }
        property.SetValue(Instance, value, null);
    }
}
01.02.2012
  • Извините, какой оператор использования мне нужен для ссылки на экземпляр. 02.02.2012
  • Вы спрашиваете, как вы можете получить доступ к внутреннему экземпляру, когда у вас есть только карта? В реализации, которую я предоставил, элемент Instance является закрытым, но вы можете поместить перед ним общедоступный элемент, а затем получить к нему доступ, например, как map.Instance. 02.02.2012
  • На самом деле нет, я вставил код в свой проект, и после добавления с помощью System.Reflection для ссылок PropertyInfo и FieldInfo все распознается, кроме Instance. Глядя на ваш код, может показаться, что для экземпляра требуется оператор использования. Я нашел экземпляр в System.Reflection.BindingFlags, но я не уверен, что это то, о чем говорит экземпляр. 02.02.2012
  • Как странно — экземпляр является членом класса PropertyMap‹T›, но сам классом не является. Я смог скомпилировать и запустить код. Возможно, если вы замените текст Instance в верхнем регистре на mWrapped и посмотрите, выдает ли он ту же ошибку? Кроме того, в какой строке возникла ошибка? 02.02.2012
  • mWrapped тоже не работал, и моя машина сильно тормозила после отладки нескольких изменений; Итак, я перезагрузил его и попробовал еще раз, и волшебным образом это сработало. Спасибо за помощь. 02.02.2012

  • 2

    Вам нужно исследовать отражение. Это относится к манипулированию метаданными типов .NET (классы, структуры, перечисления и т. д.). Однако, если вы запускаете свое приложение на общем хостинге с частичным доверием, возможно, вы вообще не сможете запускать какой-либо код отражения (ограничение безопасности на сервере). Если это так, сначала протестируйте на небольшом/быстром примере (на своем хостинге), а затем примите соответствующие решения: следует ли изменить дизайн вашего приложения или сменить хосты.

    Фрагмент, связанный с отражением, который может быть вам полезен (вставьте его где-нибудь в классе пользовательского элемента управления, так как this.GetType() имеет значение:

    var properties = this.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
    
    foreach (var p in properties)
    {
        string propertyName = p.Name;
    }
    

    Есть и другие способы получить тип; например typeof(yourclassname); вы также можете отражать/получать все типы из данной сборки (dll) и многое другое.

    01.02.2012
  • Этот ответ также очень полезен, и я могу использовать его вместо предыдущего ответа. Спасибо, Хари. 02.02.2012
  • Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..