【问题标题】:Why do unboxed types have methods?为什么未装箱的类型有方法?
【发布时间】:2011-12-16 03:17:03
【问题描述】:

为什么你可以做这样的事情

int i = 10;
i.ToString();
'c'.Equals('d');
1.ToString();
true.GetType();

在 C# 中?那里的那些东西要么是原始的、文字的、未装箱的,要么是这些东西的任何组合;那么为什么他们有方法呢? 它们不是对象,因此不应该有方法。这个语法糖是别的东西吗?如果是这样,是什么?我可以理解具有执行这些操作的函数,例如:

string ToString(int number)
{
  // Do mad code
  return newString;
}

但在这种情况下,您会将其称为函数,而不是方法:

string ranch = ToString(1);

这是怎么回事?

编辑:

刚刚意识到 C# 不再是 java 克隆,而且规则完全不同。哎呀:P

【问题讨论】:

  • 你的意思是“为什么structures 有方法”?这是因为他们只是这样做。 (谢天谢地!,曾经使用过 Java类型”。
  • 当然是对象!值类型是从 System.Object 继承的对象,并且根据“继承”的定义,具有其基类的所有方法。为什么你认为值类型不是对象?

标签: c# .net oop types boxing


【解决方案1】:

在 C# 中,所有基本类型实际上都是结构。

【讨论】:

  • -1 这个答案的问题是“原始类型”的定义不明确。你可能是对的,也可能是错的。例如,字符串通常被认为是原语,它绝对不是结构。它也无助于消除 OP 的困惑
【解决方案2】:

他们这样做是因为规范是这么说的(而且非常好):

1.28 值类型

值类型可以是结构类型或枚举类型。 C# 提供了一组预定义的结构类型,称为简单类型。 简单类型通过保留字标识。

...

1.28.4 简单类型

C# 提供了一组预定义的结构类型,称为简单类型。 简单类型通过保留字标识,但这些 保留字只是中预定义结构类型的别名 系统命名空间,如下表所述。

...

因为简单类型给结构类型起别名,所以每个简单类型都有 成员。例如,int 具有在 System.Int32 中声明的成员和 从 System.Object 继承的成员,以及以下语句 被允许:

int i = int.MaxValue; // System.Int32.MaxValue constant
string s = i.ToString(); // System.Int32.ToString() instance method
string t = 123.ToString(); // System.Int32.ToString() instance method

简单类型与其他结构类型的不同之处在于它们允许 某些附加操作:

大多数简单类型都允许通过编写文字来创建值 (§1.16.4)。例如,123 是 int 类型的文字,而 'a' 是 char 类型的文字。 C# 没有为 struct 的文字做任何规定 一般类型,其他结构类型的非默认值是 最终总是通过那些实例构造函数创建 结构类型。

正如规范所解释的,简单类型具有一些超能力,例如能够成为const、可以使用一种特殊的文字语法来代替 new,以及在编译时计算的能力(2+2实际上在最终的MSIL流中写成4)

但是方法(以及操作符)并不是一种特殊的超能力,所有结构都可以拥有它们。

规范(对于 C# 4.0,我的复制粘贴来自早期版本)可以从微软网站下载:C# Language Specification 4.0

【讨论】:

    【解决方案3】:

    Eric Lippert 最近的文章 Inheritance and Representation 解释了。(剧透:你混淆了继承和表示。)

    不知道为什么你声称整数 i、字符 'c' 和整数 1 不是对象。他们是。

    【讨论】:

    • 它们不是(嗯,它们是这个词的 C 含义,但这不是我们在 OO 代码中的意思),但在方便时可以将它们视为对象。
    • 它们是对象。请参阅 VirtualBlackFox 的回复,其中规范说“例如,int 具有在 System.Int32 中声明的成员和从 System.Object 继承的成员。” int 继承自 System.Object。有关进一步讨论,请参阅 Eric 的文章。
    • Jon:但那是编译器优化。到 IL 的时候,我们不再说 c#了
    • @Jon - 你如何解释typeof(int).BaseType.BaseType的结果?
    • 您将继承与表示混淆了。派生类不要求与基类共享内存表示。
    【解决方案4】:

    这样你就可以使用它们了!

    能这样做很方便,所以你可以。

    现在,为了做到这一点,可以将原语视为结构。例如。 32 位整数可以作为 32 位整数处理,但也可以作为public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<int>, IEquatable<int> 处理。我们大多是两全其美。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多