我在看this question,这让我很奇怪。
每当我定义一个具有自动属性的类时,
// Example A
public class MyObject
{
public int MyInt { get; set; }
}
JIT编译器会将其转换为类似于:
// Example B
public class MyObject
{
private int _MyInt;
public int get_MyInt()
{
return _MyInt;
}
public void set_MyInt(int value)
{
_MyInt = value;
}
}
所以你可以假设写下如下内容:
// Example C.1
public class MyObject
{
public int MyInt { get; set; }
public void set_MyInt(string value)
{
MyInt = int.Parse(value);
}
}
或类似的东西:
// Example C.2
public class MyObject
{
private int _myInt;
public int MyInt
{
get { return _myInt; }
set
{
_myInt = value;
}
set(string)
{
_myInt = int.Parse(value);
}
}
}
并且在没有编译器错误的情况下存在此功能。
// Example D
public void DoSomething(string someIntegerAsAString)
{
var myObject = new MyObject()
{
MyInt = someIntegerAsAString
};
}
什么阻止编译器说出示例D 之类的代码,其中推断出所需的结果并且它正常工作并且预期?功能就在那里,如示例B 所示。
这是否与语言设计师如何设计语言的工作和行为有关?
答案 0 :(得分:1)
你确实可以这样做......
public class MyObject
{
public int MyInt { get; set; }
public void set_MyInt(string value)
{
MyInt = int.Parse(value);
}
}
...尽管将字符串转换为int会有明显的性能开销。
这不起作用:
public class MyObject
{
private int _myInt;
public int MyInt
{
get { return _myInt; }
set
{
_myInt = value;
}
set(string)
{
_myInt = int.Parse(value);
}
}
}
...因为C#不支持setter
重载。但是,您可以使用implicit type conversion实现类似的功能,但必须在您自己的类型上实现。整数是一种值类型,因此它本身就是密封的。
答案 1 :(得分:1)
不是JIT
生成属性的get_*
和set_*
方法。
如果您反编译此代码:
public int MyInt { get; set; }
你会得到这个IL:
.property instance int32 MyInt()
{
.get instance int32 C::get_MyInt()
.set instance void C::set_MyInt(int32)
} // end of property C::MyInt
.method public hidebysig specialname instance int32
get_MyInt() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 11 (0xb)
.maxstack 1
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: ldfld int32 C::'<MyInt>k__BackingField'
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method C::get_MyInt
.method public hidebysig specialname instance void
set_MyInt(int32 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld int32 C::'<MyInt>k__BackingField'
IL_0007: ret
} // end of method C::set_MyInt
如果您查看PropertyInfo,则会看到它有GetMethod和SetMethod。 &#34;方法&#34;,不&#34;方法&#34;。
这与框架有关,虽然我不知道某个属性有多个getter或setter的语言。你知道这种语言吗?
答案 2 :(得分:0)
C#设计师确实让我们能够实现隐式类型转换。但是,他们可能不希望这种情况与原始类型一起使用以避免混淆。
想象一下这句话:
var myvar = 2;
myvar = "4";
任何关注上述内容的人都会认为我们正在谈论像JavaScript这样的动态语言。在JavaScript中,myvar
将是第二行的字符串。如果C#支持您描述的内容,那么它仍然是int
。例如,我会发现它令人困惑。