【问题标题】:How to extract an object name如何提取对象名称
【发布时间】:2013-10-16 13:30:29
【问题描述】:

我有一个包含子类列表的类:

public class ClassOfKb
{
    public List<Data> KbDatas {get;set;}
    public List<Product> KbProducts {get;set}
}

public class Data
{
    public Guid ID {get;set;}
    public byte[] data {get;set;}
    public string Name {get;set;}
}
public class Product
{
    public Guid ID {get;set;}
    public string Name {get;set;}
    public byte[] Image {get;set;}
}

我创建一个对象:

ClassOfKb kb = new ClassOfKb

现在我想从子对象 kb.KbDatas 中提取字符串“Datas”,我试过了:

string name = kb.KbDatas.GetType().BaseType.Name.Substring(2);

还有:

string name = kb.KbDatas.GetType().Name.Substring(2);

但是什么都没有给我我需要的东西,有什么方法可以做到这一点吗?

编辑:指定我的问题,我需要的字符串是列表的名称,除了前两个字母! KbDatas => 数据

EDIT2:我做错了,列表名和类名不同,我需要列表名

【问题讨论】:

  • 我没有看到名为“数据”的字符串。您的问题讨论了“数据”,您的代码暗示您正在尝试使用“名称”。请澄清。
  • 查看我的编辑:我想获得我列表名称的一部分
  • 调用kb.KbData.GetType() 来获取属性类型可以通过调用该属性产生副作用

标签: c# visual-studio object gettype


【解决方案1】:

如果您需要属性名称,则可以使用表达式。 下面的代码定义了提取名称舞会属性的函数:

public string GetPropertyName<T>(Expression<Func<T>> property)
{
    return ((MemberExpression)property.Body).Member.Name;
}

这会将属性转换为属性名称字符串:

GetPropertyName(()=>k.KbDatas).Substring(2)

【讨论】:

    【解决方案2】:

    你可以使用Type.GetGenericArguments来解决这个问题

           ClassOfKb kb=new ClassOfKb();
          kb.KbData = new List<Data>();
          string nameOfData = Type.GetType(kb.KbData.ToString()).GetGenericArguments().Single().Name;
    

    输出: nameOfData = 数据

          kb.KbProduct = new List<Product>();
          string nameOfProduct = Type.GetType(kb.KbProduct.ToString()).GetGenericArguments().Single().Name;
    

    输出: nameOfProduct = 产品

    【讨论】:

    • 有效,但不是我想要的,也许我的问题具有误导性,我编辑了它,知道如何使用第一个简单的功能提取列表名称吗?
    【解决方案3】:

    您可以通过反射来实现这一点。这是没有任何检查的示例 - 仅显示机制:

    PropertyInfo propertyInfo = typeof(ClassOfKb).GetProperty("KbData");
    Type propertyType = propertyInfo.PropertyType;
    Type genericArgument = propertyType.GenericTypeArguments[0];
    string name = genericArgument.Name;
    

    因为属性KbData 是通用List&lt;Data&gt;,所以您需要请求属性类型的通用参数:propertyType.GenericTypeArguments[0],并且您应该通过genericArgument.IsGenericType 测试该类型是否真的是通用的并检查通用参数计数

    【讨论】:

    • 所以似乎没有办法用自动方法来归档这个,我可以通过几个列表来获取字符串(没有在 GetProperty() 中手动指定名称,这是我期望的结果)
    • 您可以使用typeof(ClassOfKb).GetProperties() 检索所有属性并根据需要过滤它们。然后只需 foreach 所有预期的属性。
    【解决方案4】:

    如果您尝试获取属性的名称。有几种方法可以做到这一点。

    从属性本身获取通用参数的名称 - 如果您知道属性的名称。

    ClassOfKb kb = new ClassOfKb()
       { KbData = new List<Data>(), KbProduct = new List<Product>() };
    Console.WriteLine(kb.KbData.GetType().GetGenericArguments()[0].Name);
    

    如果您知道属性的数据类型,则从反射中获取属性的名称。

    System.Reflection.PropertyInfo pi = kb.GetType()
               .GetProperties()
               .FirstOrDefault(p=>p.PropertyType == typeof(List<Data>));
    Console.WriteLine(pi.Name.Substring(2)); // ignoring the kb prefix
    

    【讨论】:

      【解决方案5】:

      根据您所写的内容,您希望在 List 实例 KbData 中获取类型的名称?

      如果是这样,我想这可能就是你要找的东西:https://stackoverflow.com/a/1043778/775479

      【讨论】:

        【解决方案6】:

        试试这个

        string name = kb.KbData[0].Name.Substring(2);
        

        【讨论】:

          【解决方案7】:

          呃,既然你有一个ListData,那么就会有一个Names 序列。

          IEnumerable<string> names = kb.KbData.Select(d => d.Name);
          

          也许你只想要第一个?

          string firstName = kb.KbData.First(d => d.Name);
          

          【讨论】:

            【解决方案8】:

            由于这是一个集合,因此其中可能有多个 Data 对象,每个对象都有一个名称。您可以使用String.Join 将它们与分隔符连接起来:

            string names = string.Join(",", kb.KbData.Select(d => d.Name));
            

            如果只有一个对象,最后不会出现逗号。如果没有对象,你会得到一个空字符串。

            【讨论】:

              猜你喜欢
              • 2016-12-23
              • 2020-12-22
              • 2010-12-05
              • 2016-09-03
              • 1970-01-01
              • 2012-02-21
              相关资源
              最近更新 更多