【问题标题】:using system.reflection to list a class fileds使用 system.reflection 列出类字段
【发布时间】:2012-11-29 16:37:17
【问题描述】:

我需要获取一个列表来存储所有字段 - 类中的值

该类只是我在下面粘贴的一些公共const string 变量。

public class HTDB_Cols
{
    public class TblCustomers
    {
        public const string CustID  = "custID",
               Name  = "name",
         CustType  = "custType",
         AddDate  = "addDate",
         Address  = "address",
         City  = "city",
         Phone  = "phone",
         Cell  = "cell";
    }
}

这是一种返回字符串列表的方法,它使我能够拥有代表我所有表列名称的字符串列表,尽管由于出现错误,因此某些内容无法使用此代码

" 非静态字段需要一个目标".

public class GetClassFields
{

        public static List<string> AsList(string TableName)
        {


                    return typeof(HTDB_Cols).GetNestedTypes()
                    .First(t => String.Compare(t.Name, TableName, true) == 0)
                    .GetFields()
                    .Select(f => f.GetValue(null) as string)
                    .ToList();

        }
}

尝试如下使用它:

foreach (string tblCol in RobCS_212a.Utils.Reflct.GetClassFields.AsList      (DBSchema.HTDB_Tables.TblCustomers))
{
    Response.Write(string.Concat(tblCol, "<br />"));
}

在“DBSchema.HTDB_Cols+TblTimeCPAReport”类型上定义的字段“tbName”不是“DBSchema.HTDB_Cols”类型的目标对象上的字段。

【问题讨论】:

  • 所以您只想从该类中获取所有字段名称?
  • 一个小风格的评论:如果出现问题,返回如此复杂的操作字符串会使调试变得困难。我通常更喜欢将它分解成更小的步骤,这样如果任何一种 Linq 方法都没有返回我期望的结果,我可以很容易地破译它是什么。无论如何,编译器都会将它们重新合并在一起,但它会使代码更具可读性和可维护性。
  • @MikeParkhill mike,第二次投赞成票是我,原因是,我喜欢保留东西,就像你说我不应该保留的一样,你说的好点,好像有人不这样做但是知道编译器的工作原理你可能会担心你“过度加载”给 cpu 的指令,因为......(如果......你没有把它分解)它应该更快(对 CPU 的指令更少) 实时这是错误的假设,所以为那个评论喝彩

标签: c# .net reflection


【解决方案1】:

您的代码很接近。有两个问题,都位于您的 linq select 方法调用的参数中:

  • 您的 HTDB_Cols 类是一个非静态类,您尝试检索的字符串值是实例成员。因此,当您尝试从类中提取实例成员时,您必须将类的实例传递给 FieldInof.GetValue 方法。在下面的代码中,我在变量“instanceOfClass”中创建了您的类的实例。您可以在FieldInfo class

  • 的文档中看到这一点
  • 从 FieldInfo.GetValue 返回的值是一个对象。您必须使用 ToString 方法或 (string) cast 将其显式转换为字符串。

通过这两个更改,您的方法有效。清单如下:

public class GetClassFields
{
    public static List<string> AsList(string tbl)
    {
        var instanceOfClass = new HTDB_Cols();
        return typeof(HTDB_Cols).GetNestedTypes()
                                .First(t => String.Compare(t.Name, tbl, true) == 0)
                                .GetFields()
                                .Select(f => f.GetValue(instanceOfClass).ToString())
                                .ToList<String>();
    }
}

你可以这样调用这个函数:

var fields = GetClassFields.AsList("TblCustomers");

返回所需信息:

【讨论】:

  • 你真是太好了,我得到的最好的全面深入的答案......干杯!
  • @span class="comcopy">@sorry 我有一个例外,因为我在其他一些类上尝试了它,另一个表,因为我仍处于测试阶段,其中一个表类,持有字符串而不是 const 字符串 - 抛出这个因为我更新了我的帖子,我能理解为什么会这样吗?在字符串情况下而不是在 const 字符串上?
  • 如果您将在 test 中省略 const 标志。在我修好第二节课之前,你会得到我所得到的……通过将其更改为应有的方式 - const string somecolumn = "sumcolumn"。对此有简单的解释吗?
  • 我省略了 const 标志,在我的示例中仍然可以正常工作。如果没有看到代码,我无法准确说出问题所在,但您的错误消息表明您正在传递 DBSchema.HTDB_Cols+TblTimeCPAReport 对象而不是 DBSchema.HTDB_Cols 或反之亦然。如果您将要传递的对象的类型切换为应该更正它的其他类型。
  • 我会通知你,因为我真的需要知道(虽然我不需要这些类中的任何一个来保存可能被覆盖的字符串,所以它们必须是只读或常量)但是 我的追求是在系统反射和 decleration 修饰符的概念之后,不亚于完成这个项目,我正在提出一个新问题,以便我会通知你,不应该从这个评论中花费超过 10 分钟, 不客气
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 2011-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多