【问题标题】:How to "customize" the Name of a type, like Nullable?如何“自定义”类型的名称,例如 Nullable?
【发布时间】:2017-09-08 22:31:22
【问题描述】:

Nullable 类是如何做到的?

public class Foo<T>
{
    public T Bar { get; set; }
}

var n1 = new Nullable<int>(123).GetType().Name; // "Int32"
var n2 = new Foo<int>().GetType().Name; // "Foo`1"

是否可以使Foo 具有相同的类型名称,即“Int32”?

【问题讨论】:

  • 请注意,Nullable 在运行时得到了一些非常特殊的处理。特别是,如果没有值的 Nullable 被装箱,则装箱的对象是 null - 与所有其他值类型相反。我怀疑这是类似的特殊待遇。
  • 另见How is ValueType.GetType() able to determine the type of the struct?。因为Nullable&lt;T&gt;ValueType 并且值类型是装箱的,所以这就是你得到的(另见Nullable.cs 源代码)
  • 答案是我的评论和@AdrianoRepetti 的结合。我会起草一个答案。

标签: c#


【解决方案1】:

tl;dr:不,您不能更改 Foo 的名称。您在Nullable 中看到的是可空值被装箱的副作用。


有几件事会导致您看到有关 Nullable 类型的行为:

  • 在值类型上调用 .GetType() 会导致该值为 boxed
  • Nullable 得到运行时关于拳击的特殊处理。 Nullable 本身永远不会被装箱,而是:
    • 如果Nullable 包含一个值,则该值将被装箱(在本例中int 值为123)。
    • 如果Nullable 不包含值,则装箱操作的计算结果为null

结果是,在您的代码中,Object.GetType() 在执行时看到的是一个装箱的 int 值,不是一个装箱的 Nullable&lt;int&gt; 对象(因为这又是不可能的)。这就是为什么可为空的名称与其内容的名称相同的原因。这是演示正在发生的事情的最简单方法:

new Nullable<int>(123).GetType() == typeof(int)
new Nullable<int>(123).GetType() != typeof(Nullable<int>)

作为旁注,因为没有值的 nullable 框为 null,it's an error 对 null nullable 调用 .GetType()!这同时是有意义的(它是 null,对吗?)并且没有意义(它是一个值类型......它不能真的为 null!)。当 nullable 没有值时,您可以调用方法Nullable 本身上实现或覆盖(因为这些调用不需要装箱),但您不能 调用方法Object 继承而不被覆盖

Nullable具有奇怪的双重性格,有时会造成这样的惊喜。

现在我们知道了 Nullable 的情况,我们可以看到 Nullable 实际上并没有重命名自己 - 您看到的类型的名称是可空装箱行为的结果。

【讨论】:

    猜你喜欢
    • 2014-09-28
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多