Вопрос о чтении свойств класса во время выполнения в c # (.NET 2.0)? - PullRequest
0 голосов
/ 18 ноября 2009

Допустим, у меня есть класс, который имеет 3 свойства.Я не знаю, какое свойство я хочу прочитать до времени выполнения.Есть ли способ сделать это без оператора switch / if-else?

Если DataTable обрабатывается как класс, то столбцы могут обрабатываться динамически, что сработает, но я не могу изменитьмой класс в DataTable (длинная история).

Для DataTable код будет:

string columnName = "Age";
int age = dataRow[columnName];

Как это возможно в классе?

string propertyName = "Baka";
int age = item.getProperty(propertyName)  // ???

Ответы [ 7 ]

2 голосов
/ 19 ноября 2009

РЕДАКТИРОВАТЬ: Я только что прочитал ваш комментарий о неиспользовании переключателя, но я все равно оставлю это здесь, на всякий случай ... перейдите ко второму ответу .

Может быть, что-то вроде этого:

public enum Property { Name, Age, DateOfBirth};

public T GetProperty<T>(Property property)
{
    switch (property)
    {
       case Property.Name:
          return this.Name;
       // etc.
    }
}

Я не слишком силен в генетике, так что, возможно, кто-то может помочь мне с ответным броском.


Кроме того, вы можете добавить поле в свой класс типа DataRow и использовать индексатор для доступа к нему:

public class MyClass
{
   DataTable myRow = null;
   MyClass(DataRow row)
   {
      myRow = row;
   }

   public object this[string name]
   {
      get
      {
         return this.myRow[name];
      }
      set
      {
         this.myRow[name] = value;
      }
   }
}

Использование:

MyClass c = new MyClass(table.Rows[0]);
string name = c["Name"].ToString();
2 голосов
/ 18 ноября 2009

Самый простой способ выполнить такую ​​оценку во время выполнения - это Отражение .

В зависимости от используемой версии .NET вы можете добавлять методы в свой класс или использовать методы расширения.

1 голос
/ 19 ноября 2009

Если вы знаете тип объекта, вы можете получить все свойства, а затем запрошенное свойство, используя отражение.

MyClass o;

PropertyInfo[] properties = o.GetType().GetProperties(
    BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

Каждое PropertyInfo имеет имя, которое вы можете сопоставить с вашей строкой.

1 голос
/ 19 ноября 2009

Ответил на аналогичный вопрос ранее. Вот пример кода и ссылка на другой вопрос. Скрытие публичных функций

Вас больше всего заинтересует метод GetValue класса System.Reflection.PropertyInfo.

Пример кода C #

public bool SetProperty(object obj, string PropertyName, object val)
{
    object property_value = null;
    System.Reflection.PropertyInfo[] properties_info = obj.GetType.GetProperties;
    System.Reflection.PropertyInfo property_info = default(System.Reflection.PropertyInfo);
    
    foreach (System.Reflection.PropertyInfo prop in properties_info) {
        if (prop.Name == PropertyName) property_info = prop; 
    }
    
    if (property_info != null) {
        try {
            property_info.SetValue(obj, val, null);
            return true;
        }
        catch (Exception ex) {
            return false;
        }
    }
    else {
        return false;
    }
}

public object GetProperty(object obj, string PropertyName)
{
    object property_value = null;
    System.Reflection.PropertyInfo[] properties_info = obj.GetType.GetProperties;
    System.Reflection.PropertyInfo property_info = default(System.Reflection.PropertyInfo);
    
    foreach (System.Reflection.PropertyInfo prop in properties_info) {
        if (prop.Name == PropertyName) property_info = prop; 
    }
    
    if (property_info != null) {
        try {
            property_value = property_info.GetValue(obj, null);
            return property_value;
        }
        catch (Exception ex) {
            return null;
        }
    }
    else {
        return null;
    }
}

Пример кода VB

Public Function SetProperty(ByVal obj As Object, ByVal PropertyName As String, ByVal val As Object) As Boolean
    Dim property_value As Object
    Dim properties_info As System.Reflection.PropertyInfo() = obj.GetType.GetProperties
    Dim property_info As System.Reflection.PropertyInfo

    For Each prop As System.Reflection.PropertyInfo In properties_info
        If prop.Name = PropertyName Then property_info = prop
    Next

    If property_info IsNot Nothing Then
        Try
            property_info.SetValue(obj, val, Nothing)
            Return True
        Catch ex As Exception
            Return False
        End Try
    Else
        Return False
    End If
End Function

Public Function GetProperty(ByVal obj As Object, ByVal PropertyName As String) As Object
    Dim property_value As Object
    Dim properties_info As System.Reflection.PropertyInfo() = obj.GetType.GetProperties
    Dim property_info As System.Reflection.PropertyInfo

    For Each prop As System.Reflection.PropertyInfo In properties_info
        If prop.Name = PropertyName Then property_info = prop
    Next

    If property_info IsNot Nothing Then
        Try
            property_value = property_info.GetValue(obj, Nothing)
            Return property_value
        Catch ex As Exception
            Return Nothing
        End Try
    Else
        Return Nothing
    End If
End Function
0 голосов
/ 19 ноября 2009

Пример использования indexers :

public class MyItem
{
    public object this[string name]
    {
        switch (name)
        {
            case "Name":
                return "Wikipetan";
            case "Age":
                return 8;
            case "DateOfBirth":
                return new DateTime(2001, 01, 15);
            case "Baka":
                return false;
            default:
                throw new ArgumentException();
        }
    }
}

Использование:

MyItem item = ...;
string propertyName = "Age";
int age = (int)item[propertyName];
0 голосов
/ 19 ноября 2009
string propertyToGet = "SomeProperty";
SomeClass anObject = new SomeClass();

string propertyValue = 
    (string)typeof(SomeClass)
    .GetProperty("SomeProperty")
    .GetValue(anObject, null);
0 голосов
/ 19 ноября 2009

item.GetProperties () вернет PropertyInfo [], содержащую все свойства (думаю, только для общего доступа)

Объект PropertyInfo имеет свойство Name, которое является именем свойства, поэтому вы можете выполнять итерацию по массиву в поисках объекта PropertyInfo с вашим поисковым именем.

...