在所有情况下,代码中的字符串"hello"
都不涉及对构造函数的调用。它是一个常量值,在编译时创建,这样字符串"hello"
的所有实例都是同一个对象。类似地,整数1
和十进制值3.456
,以及任何其他“文字”值,都是在运行时之前存在的常量,在构造函数代码有机会被调用之前。
new string("hello");
无法调用该代码,因为没有将字符串作为值的字符串构造函数。但是,如果您将其更改为new string("hello".ToCharArray());
,您将获得一个字符串对象,但它与字符串不同"hello"
。您实际上已经在一个单独的内存位置创建了一个新字符串,来自 plain "hello"
。它只是碰巧包含与"hello"
.
意义在于,如果您确实使用了隐式类型转换技巧,那么转换为您的类型的一个字符串文字将不是同一个对象:
class Foo
{
private string value;
public Foo(string val)
{
this.value = val;
}
public static implicit operator Foo(string value)
{
return new Foo(value);
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Foo a = "asdf";
Foo b = "asdf";
Assert.AreNotEqual(a, b);
}
}
换句话说,a.Equals(b)
返回 false。为了使 Equals 方法返回 true,您必须在 Foo 类中重写 Equals 方法。
public override bool Equals(object obj)
{
return obj is Foo && value.Equals(((Foo)obj).value);
}
但是,正如其他海报所提到的,这是一种混淆。您将难以使用代码以及难以调试它。它将看起来像常规分配的内容更改为完整的方法调用。它破坏了 Visual Studio 为检查代码提供的许多工具,例如 F12 跳转到方法定义。
隐式类型转换应仅在两种类型在使用中实际上可以互换的情况下使用,它们的功能存在细微差别。该float
类型可以隐式转换为,因为vsdouble
没有额外的方法和函数,并且从to增加精度不会改变值。但是,从to需要显式转换,因为精度的损失会改变表示的值。double
float
float
double
double
float