【问题标题】:How to get declared types using reflection [duplicate]如何使用反射获取声明的类型
【发布时间】:2020-03-29 03:34:19
【问题描述】:

我正在尝试使用反射来获取声明的类型。它适用于不可为空的类型,但适用于可空类型。

class Product
{
    public decimal Price { get; set; }
    public decimal? OfferPrice { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        Type t = typeof(Product);
        var properties = t.GetProperties();
        PropertyInfo price_pInfo = t.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name == "Price").FirstOrDefault();
        Console.WriteLine("Member 'Price' was defined as " + price_pInfo.PropertyType);


        PropertyInfo offerprice_pinfo = t.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name == "OfferPrice").FirstOrDefault();
        Console.WriteLine("Member 'OfferPrice' was defined as " + offerprice_pinfo.PropertyType);

    }

输出:

Member 'Price' was defined as System.Decimal
Member 'OfferPrice' was defined as System.Nullable`1[System.Decimal] //I am expecting to get Nullable<System.Decimal>

【问题讨论】:

  • “我期望得到 Nullable 这不是类型的名称。系统返回给您的名称是。如果您想要在 C# 代码中看到的名称,则由您编写代码以将构造类型的名称转换回 C# 样式的名称。
  • @PeterDuniho 这个问题专门针对可空类型。由于它的语法,例如decimal?,对于某些人来说他们处理的是泛型类可能并不明显。出于这个原因,我认为这个问题对社区有价值。请考虑重新开放。
  • @JeremyTCD:“这个问题专门针对可空类型”——不,不是。它是关于泛型类型,以及构造泛型类型的 .NET 名称与 C# 程序员习惯看到的名称之间的区别。它与标记的副本完全相同。更糟糕的是,您给出的答案甚至没有完成问题作者所要求的,而标记副本中的建议却做到了。

标签: c# nullable system.reflection propertyinfo


【解决方案1】:

decimal?Nullable&lt;decimal&gt; 的语法糖,它是一个通用类型。运行时将Nullable&lt;decimal&gt; 表示为“System.Nullable`1[decimal]”。来自official docs

泛型类型的名称以反引号 (`) 结尾,后跟表示泛型类型参数数量的数字。此名称修饰的目的是允许编译器支持具有相同名称但具有不同数量的类型参数的泛型类型,发生在相同的范围内。

没有内置方法来检索泛型类型的代码内表示,您必须手动编辑类型名称。既然你只关心Nullable&lt;T&gt;

public static string GetNullableTypeCodeRepresentation(string typeName)
{
    return Regex.Replace(typeName, @"\.Nullable`1\[(.*?)\]", ".Nullable<$1>");
}

然后:

static void Main(string[] args)
{
    Type t = typeof(Product);
    var properties = t.GetProperties();
    PropertyInfo price_pInfo = t.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name == "Price").FirstOrDefault();
    Console.WriteLine("Member 'Price' was defined as " + price_pInfo.PropertyType);

    PropertyInfo offerprice_pinfo = t.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name == "OfferPrice").FirstOrDefault();
    Console.WriteLine("Member 'OfferPrice' was defined as " + GetNullableTypeCodeRepresentation(offerprice_pinfo.PropertyType.ToString()));
}

打印:

Member 'Price' was defined as System.Decimal
Member 'OfferPrice' was defined as System.Nullable<System.Decimal>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 2012-04-03
    • 2020-05-31
    • 2015-01-10
    • 2019-05-28
    • 2011-03-03
    • 1970-01-01
    相关资源
    最近更新 更多