关于在 C# (.NET 2.0) 中运行时读取类属性的问题?

发布于 2024-08-11 21:49:19 字数 384 浏览 2 评论 0原文

假设我有一个具有 3 个属性的类。直到运行时我才知道要读取哪个属性。有没有办法在没有 switch/if-else 语句的情况下做到这一点?

如果将 DataTable 视为一个类,则可以动态处理列,这可以工作,但我无法将我的类更改为 DataTable (长话短说)。

对于 DataTable,代码将是:

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

这在类中怎么可能?

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

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 columnName = "Age";
int age = dataRow[columnName];

How is this possible in a class?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

烟雨扶苏 2024-08-18 21:49:19

进行这种运行时评估的最简单方法是使用 Reflection

根据您使用的 .NET 版本,您可以向类添加方法或使用扩展方法。

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.

郁金香雨 2024-08-18 21:49:19

编辑:我刚刚阅读了您关于不使用开关的评论,但无论如何我都会将其保留在这里,以防万一......跳到我的第二个答案

也许是这样的:

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();

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();
妄司 2024-08-18 21:49:19

之前回答过类似的问题。这是一个代码示例,并链接到另一个问题。
隐藏公共函数

您最感兴趣的是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

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
念三年u 2024-08-18 21:49:19

如果您知道对象的类型,则可以使用反射获取所有属性,然后获取您请求的属性。

MyClass o;

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

每个 PropertyInfo 都有一个名称,您可以将其与您的字符串相匹配。

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.

倾`听者〃 2024-08-18 21:49:19

item.GetProperties() 将返回一个包含所有属性的 PropertyInfo[](我认为仅是公共的)

PropertyInfo 对象有一个属性名称,它是属性的名称,因此您可以通过搜索迭代搜索 PropertyInfo 对象的数组姓名。

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.

凉世弥音 2024-08-18 21:49:19
string propertyToGet = "SomeProperty";
SomeClass anObject = new SomeClass();

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

string propertyValue = 
    (string)typeof(SomeClass)
    .GetProperty("SomeProperty")
    .GetValue(anObject, null);
樱娆 2024-08-18 21:49:19

使用索引器的示例:

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

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];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文