将ToUpper作为Char

时间:2016-07-24 04:46:23

标签: c#

在C#中,我们在类型字符串上有这个非静态方法:

"abc".ToUpper()

但是对于char,我们需要使用静态方法:

char.ToUpper('a')

在向初学者介绍c#时,他们总是希望能够编写以下内容:

'a'.ToUpper()

有没有人有这样设计的见解?

我唯一能想到的就是性能,但我也期望为类型字符串提供一个静态的ToUpper()。

3 个答案:

答案 0 :(得分:1)

区别在于stringreference type,而char是代表.Net Framework Char Structure的关键字。当你调用Char.ToUpper('a')时,你实际上是在C#中使用字符串结构。结构是Value Types。值类型是不可变的。

由于结构是不可变的,因此对结构本身起作用的方法不能按预期工作(see Why are Mutable Structs Evil)。因此需要静态方法。调用Char.ToUpper(aChar)时,实际上并没有更改aChar,而是创建一个新的字符实例,它是作为参数传递并返回的字符的大写字母。以下示例演示了这一点。

Char aChar = 'a';
Char.ToUpper(aChar);
//aChar still equals 'a'

Char bChar = 'b';
bChar = Char.ToUpper(bChar);
//bChar now equals 'B'

char有其他允许你执行'a'.Equals('a');之类的方法的原因是因为值类型和引用类型都继承自Object,它定义了那些方法(从技术上讲,值类型的类型为{ {1}},继承自System.ValueType)。这些方法不会对对象本身进行任何更改。

编辑 - 为什么这个问题实际上是猜测

我非常好奇,看看是否有“为什么System.Object没有char方法”的实际答案,我决定查看CSharp 5 Language Specification Document,我找到了以下内容:

.ToUpper()是一个积分类型(第80页),它是简单类型的子集。简单类型本身只是预定义的结构类型。结构类型是“可以声明常量,字段,方法,属性,索引器,运算符,实例构造函数,静态构造函数和嵌套类型”的值类型“(第79页)。

char是一种类型,它是一种参考类型(第85页)。类类型定义“包含数据成员(常量和字段)的数据结构,函数成员(方法,属性,事件,索引器,运算符,实例构造函数,析构函数和静态构造函数)和嵌套类型” (第84页)。

此时,string s显然可以支持char方法(这就是扩展方法有效的原因)。但是,正如问题所述,他们不支持。 在这一点上,我确信任何关于为什么这是真的的推理都是纯粹的推测(当然,除非你是C#团队的成员)。

答案 1 :(得分:0)

Hans Passant提到可以通过扩展方法轻松实现此语法。我会在这里提供代码,以防任何人对使用该语法深感依恋。

public static class MyExtensionMethods
{
    public static char ToUpper( this char c )
    {
        return char.ToUpper( c );
    }
}

然后你可以这样做:

'a'.ToUpper()

答案 2 :(得分:0)

(抱歉,评论中没有足够的空间 - 我知道这不是一个完整的答案。)

这似乎是所有原始类型的模式;例如,intdoublebool也没有方法(ToString()个变种除外)。所以它不仅仅是char - 它是c#定义的所有原始类型的属性。

我猜(并且这是猜测),无论何时访问数据,您都要直接访问RAM的位 - 原始值如intchar以及{{1 - 或者您正在访问像对象或结构一样的.NET构造。 char在特定内存地址处始终为2个字节。因此框架可以将其视为原始内存位置。

如果我们尝试将原始RAM视为对象,您将要么必须“装箱”所有工作,或者只是不可能。我的猜测是你不能在基元上做一些像virtual method dispatch这样的核心功能,并且对象的世界和基元的世界必须分开。

无论如何,希望在某种程度上促进谈话......