开发者

Question about reading properties of a class at run time in c# (.NET 2.0)?

开发者 https://www.devze.com 2022-12-11 16:13 出处:网络
Let\'s say I have a class that has 3 properties. I don\'t know which property I want to read until runtime. Is there a way to do this without a switch/if-else statement?

Let's say I have a class that has 3 properties. I don't know which property I want to read until runtime. Is there a way to do this without a switch/if-else statement?

If a DataTable is treated as a class, then the columns can be treated dynamically which would work, but I'm not able to change my class into a DataTable (long story).

For a DataTable, the code would be:

string colu开发者_C百科mnName = "Age";
int age = dataRow[columnName];

How is this possible in a class?

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


The easiest way to do this kind of runtime evaluation is with Reflection.

Depending on the version of .NET you're using, you could add methods to your class or use extension methods.


EDIT: I just read your comment about not using a switch, but I'll keep this here anyway, just in case... skip to my second answer.

Maybe something like this:

public enum Property { Name, Age, DateOfBirth};

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

I'm not too strong in Genetics, so maybe someone can help me with the return cast.


Alternatively, you could add a field to your class of type DataRow and use an indexer to access it:

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;
      }
   }
}

Usage:

MyClass c = new MyClass(table.Rows[0]);
string name = c["Name"].ToString();


Answered a similar question earlier. Here's a code sample, and link to the other question. Hiding Public Functions

You're going to be most interested in the GetValue method of the System.Reflection.PropertyInfo class.

C# Code Sample

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 Code Sample

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


If you know the type of object you can get all the properties, and then your requested property, using reflection.

MyClass o;

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

Each PropertyInfo has a Name which you can match up to your String.


item.GetProperties() would return a PropertyInfo[] containing all properties (public only I think)

A PropertyInfo Object has a property Name which is the name of the property, so you can iterate over the array searching for a PropertyInfo object with your search name.


string propertyToGet = "SomeProperty";
SomeClass anObject = new SomeClass();

string propertyValue = 
    (string)typeof(SomeClass)
    .GetProperty("SomeProperty")
    .GetValue(anObject, null);


Example using 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();
        }
    }
}

Usage:

MyItem item = ...;
string propertyName = "Age";
int age = (int)item[propertyName];
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号