【问题标题】:c# - how can i get an attribute from an instanced generic class?c# - 如何从实例化的泛型类中获取属性?
【发布时间】:2012-08-11 09:09:37
【问题描述】:

从之前的thread我问过如何以通用的方式从一个id中获取注册表,我得到的答案是这样的:

    public class DBAccess
{
    public virtual DataBaseTable GetById<DataBaseTable>(int id, Table<DataBaseTable> table) where DataBaseTable : class
    {
        var itemParameter = Expression.Parameter(typeof(DataBaseTable), "item");
        var whereExpression = Expression.Lambda<Func<DataBaseTable, bool>>
            (
            Expression.Equal(
                Expression.Property(
                    itemParameter,
                    "Id"
                    ),
                Expression.Constant(id)
                ),
            new[] { itemParameter }
            );
        return table.Where(whereExpression).Single();
    }
}

这很好用,但现在我不知道如何获取它的任何属性,提出一个具体的问题,我怎样才能使下面的函数工作?

    public static int GetRelatedTableId<DataBaseTable>
    (Table<DataBaseTable> table,String RelatedTableId) where DataBaseTable : class
    {
        DBAccess RegistryGet = new DBAccess();    
        DataBaseTable tab = RegistryGet.GetById<DataBaseTable>(id, table);
        return tab.getAttributeByString(RelatedTableId);//i just made this up
    }

更新解决方案

感谢下面的链接,我设法解决了这个问题

    public static int GetRelatedTableId<DataBaseTable>
    (Table<DataBaseTable> table,String RelatedTableId) where DataBaseTable : class
    {
        DBAccess RegistryGet = new DBAccess();    
        DataBaseTable tab = RegistryGet.GetById<DataBaseTable>(id, table);
        return (int)(tab.GetType().GetProperty(RelatedTableId)).GetValue(tab, null);
    }

【问题讨论】:

    标签: c# database linq generics


    【解决方案1】:

    如果您的属性名称仅在运行时已知,那么您可以使用反射检查类型 DataBaseTable,按名称查找感兴趣的属性,然后从您的实例 tab 中检索其值。

    请参阅此问题的答案以获取示例:How can I get the value of a string property via Reflection?

    澄清:是的,您的类型是通用参数,但typeof(DataBaseTable)tab.GetType() 仍允许您检查正在使用的特定类型。

    【讨论】:

      【解决方案2】:

      如果您只在运行时知道属性名称,请使用反射......虽然这通常是一种代码味道。

      如果您在编译时知道属性名称但不知道具体类型(并且正在使用 .net 4),则将返回值转换为 dynamic 并正常访问该属性。

      如果你在编译时知道具体的类型和属性,将返回值转换为返回的类型并正常访问该属性。

      也基于提供的片段,您的代码可能应该是

      public class DBAccess<T> where T : class
      {
          public virtual T GetById(int id, Table<T> table)
          {
      

      public static class DBAccess 
      {
          public static T GetById<T>(int id, Table<T> table) where T : class
          {
      

      【讨论】:

      • 我不同意使用反射通常是一种代码味道。您可以在许多广泛使用且经过深思熟虑的库中找到反射。它是一个和其他工具一样的工具。
      猜你喜欢
      • 2023-03-19
      • 2020-01-29
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      • 2023-03-21
      相关资源
      最近更新 更多