有关C#语言规范中隐式转换的问题

时间:2010-09-17 15:38:44

标签: c# language-features implicit-conversion language-specifications

第6.1节隐式转化因此定义了身份转换

  

身份转换从任何类型转换为相同类型。存在这种转换,使得已经具有所需类型的实体可以被称为可转换为该类型。

现在,这些句子的目的是什么?

  

(在§6.1.6隐式参考转换中)

     

隐式参考转换是:

     
      
  • [...]
  •   
  • 从任何引用类型引用类型 T,如果它具有隐式标识或引用转换为引用类型< / em> T 0 T 0 的身份转换为T
  •   

  

(在§6.1.7拳击转换中)

     
      
  • 如果值类型具有到接口类型I 0 I I的装箱转换> 0 的身份转换为I
  •   

最初它们似乎是多余的(同义词)。但他们必须出于某种目的,所以为什么他们在那里?

您能举例说明两种类型T 1 T 2 ,以便T 1 可隐式转换为T 2 ,如果它不适用于上述段落?

4 个答案:

答案 0 :(得分:6)

答案 1 :(得分:2)

规范的第4.7节指出存在从Foo<dynamic>Foo<object>的身份转换,反之亦然。您引用的规范部分是为了确保处理此案例而编写的。也就是说,如果存在从T到C<object, object>的隐式引用转换,那么还会隐式引用转换为C<object, dynamic>C<dynamic, object>C<dynamic, dynamic>

有人可能会合理地指出:(1)这些短语的意图并不明显 - 因此你的问题 - 而且令人困惑;(2)关于身份转换的部分应该交叉引用有关动态转换的部分,以及( 3)规范中的这样的短语使得规范的实现者难以将规范语言清楚地转换为实现。如何知道是否存在任何此类类型?规范不需要指定精确的算法,但如果它提供更多的指导,那将是很好的。

遗憾的是,该规范并不是一份完美的文件。

答案 2 :(得分:0)

  

身份转换会转换   任何类型的相同类型。这个   存在转换,以便一个实体   已经有必需的类型可以   据说可兑换成那个   类型。

这表示在C#-land中,1 == 1;锹是一个锹。这是将对象引用分配给相同类型的变量的基础;如果变量类型T1和一个类型T2实际上都是黑桃,则可以将一个分配给另一个,而不必将其中一个显式转换为Spade。想象一下C#变体,其中赋值必须如下所示:

Spade mySpade = new Spade();
Spade mySpade2;

mySpade2 = (Spade)mySpade; //explicit cast required

此外,数学中的“同一性”表明,给定一组输入的结果的表达式等价于给定相同输入产生相同结果的另一个表达式。在编程中,这意味着计算类型实例的表达式或函数等效于该类型,而不进行显式转换。如果不成立,则需要以下代码:

public int myMethod() { /*Do something*/ }
...
int myInt = (int)myMethod(); //required even though myMethod() evals to an int.
...
int myInt = (int)(1 + 2); //required even though 1, 2, and 1+2 eval to an int.

第二条规则基本上说,如果某个成员变量(按定义为盒装类型,因为它的容器是引用类型)被声明为一个类,则可以将值类型分配给类上的成员变量相同的类型。如果未指定此规则,理论上可能存在一个C#版本,其中纯值类型必须显式转换为其引用模拟,以便作为成员变量存储在类中。想象一下,例如,一个C#版本,其中blue关键字类型(int,float,decimal)和浅蓝色类名称(Int32,Float,Decimal)引用两个非常不同的,只能显式转换的类型,以及int ,float,decimal等作为成员变量类型不合法,因为它们不是引用类型:

public class MyClass
{
  Int32 MyBoxedValueType; //using "int" not legal
}

...

MyClass myClass = new MyClass();
int theInt = 2;

myClass.MyBoxedValueType = (Int32)theInt; //explicit cast required

我知道这听起来很愚蠢,但在某种程度上,必须知道这些事情,而在计算机中,你必须指定一切。有时读冰岛美国曲棍球规则手册;本书的第一条规则是游戏应该在冰面上进行。它是最终的“好伙伴”之一,但也是必须理解的游戏的基本事实,以便任何其他规则有意义。

答案 3 :(得分:-1)

无论是否实现Convert.ChangeType(client, typeof(Client)),代码都可以在IConvertible调用时保证传递。

使用Reflector查看来自ChangeType的{​​{1}}的来源,并注意mscorlib按原样返回的条件。

请记住,value运算符不是转化,只是参考集。因此=之类的代码不会执行任何隐式转换。如果声明了身份隐式转换,则会发出错误CS0555

我想规范说让C#编译器处理这种情况,因此 dot not 手动尝试定义身份转换。