在Jesse Liberty的Learning C#书中,他说"一种类型的物体可以转换成另一种类型的物体.这就是所谓的铸造."
如果您调查从下面的代码生成的IL,您可以清楚地看到转换的赋值与转换的赋值没有做同样的事情.在前者中,你可以看到拳击/拆箱发生; 在后者中,您可以看到对convert方法的调用.
我知道最终它可能只是一个愚蠢的语义差异 - 但是只是转换了另一个词.我并不是故意嗤之以鼻,但我对任何人的直觉都不感兴趣 - 意见不计算在这里!任何人都可以指出确认或否认铸造和转换是否相同的确定性参考?
object x;
int y;
x = 4;
y = ( int )x;
y = Convert.ToInt32( x );
Run Code Online (Sandbox Code Playgroud)
谢谢
RP
注意在Matt关于显式/隐式的评论后添加:
我不认为隐含/显性是不同的.在我发布的代码中,两种情况下的更改都是明确的.隐式转换是指向int分配short时发生的情况.
Sklivvz注意事项:
我想要确认我对Jesse Liberty(通常是清晰和清晰)语言松散的怀疑是正确的.我以为Jesse Liberty的语言有点松散.我知道转换是在对象层次结构中路由的 - 也就是说,您不能从整数转换为字符串,但是您可以从从System.Exception派生的自定义异常转换为System.Exception.
但有趣的是,当您尝试从int转换为字符串时,编译器会告诉您它无法"转换"该值.也许杰西比我想象的更正确!
JIT编译器和CLR有什么区别?如果您将代码编译为il并且CLR运行该代码,那么JIT正在做什么?JIT编译如何通过向CLR添加泛型来改变?
为什么C#泛型不能像C++模板中那样从泛型类型参数中派生出来?我的意思是我知道这是不可能的,因为CLR不支持这个,但为什么呢?
我知道C++模板和C#泛型之间的深刻差异 - 前者是编译时实体,必须在编译期间解析,而后者是一流的运行时实体.
不过,我没有看到的原因,为什么CLR的设计者并没有拿出一个方案,该方案将最终使CLR泛型类型从泛型类型参数的一个派生.毕竟,这将是非常有用的功能,我个人非常想念它.
编辑:
我想知道一个核心问题,解决这个问题会产生如此高的代价来实现这个功能,这个功能证明它还没有得到实施.例如,检查这个虚构的声明:
class C<T> : T
{
}
Run Code Online (Sandbox Code Playgroud)
正如Eric Lippert已经注意到" 如果T是一个结构怎么办?如果T是一个密封的类型怎么办?如果T是一个接口类型怎么办?如果T是C怎么办?如果T是从C语言中得到什么怎么办?"如果T是带抽象方法的抽象类型?如果T的可访问性低于C怎么办?如果T是System.ValueType怎么办?(你能否有一个继承自System.ValueType的非结构?)System.Delegate怎么样? System.Enum等等? "
正如埃里克继续说的那样," 那些是容易的,显而易见的 ".的确,他是对的.我感兴趣的是一个既不容易也不明显的问题的具体例子,这个问题很难解决.
我需要在我的应用程序中使用跨appdomain调用,有时我有这个RemotingException:
对象'/2fa53226_da41_42ba_b185_ec7d9c454712/ygiw+xfegmkhdinj7g2kpkhc_7.rem'已断开连接或在服务器上不存在.
目标对象仍然存在,我已经检查过了.
UPD我在目标对象的终结器中设置断点,它永远不会命中.因此,这个对象是活着的,而不是GC.
编辑:底部的评论.还有,这个.
这就是让我感到困惑的一点.我的理解是,如果我有这样的枚举......
enum Animal
{
Dog,
Cat
}
Run Code Online (Sandbox Code Playgroud)
...我基本上完成的是定义了一个用两个定义的值调用的值类型Animal,Dog和Cat.这种类型派生自引用类型 System.Enum(值类型通常不能执行的操作 - 至少不在C#中 - 但在这种情况下是允许的),并且具有用于在int值之间来回转换的工具.
如果我刚刚描述上面的枚举类型的方式是真的,那么我希望以下代码抛出InvalidCastException:
public class Program
{
public static void Main(string[] args)
{
// Box it.
object animal = Animal.Dog;
// Unbox it. How are these both successful?
int i = (int)animal;
Enum e = (Enum)animal;
// Prints "0".
Console.WriteLine(i);
// Prints "Dog".
Console.WriteLine(e);
}
}
Run Code Online (Sandbox Code Playgroud)
通常,您不能将值类型System.Object从其确切类型以外的任何其他方式取消装箱.那以上怎么可能呢?这是因为如果该 …
我正在阅读Ivor Horton的Beginning Visual C++ 2008,其许多CLR示例都有main的定义:
int main(array<System::String ^> ^args)
Run Code Online (Sandbox Code Playgroud)
我一页又一页地回到书的开头找到第一个这样的实例,并解释了它的真正含义,但找不到一个.
显然它意味着与标准相同int main(int argc, char *argv[]),但我想知道^实际使用的时间和原因,以及为什么它甚至存在(它是否做了指针*和引用&无法表示的东西)?
有没有人知道针对.NET CLR/DLR的ECMAScript 的真实(i ..无蒸发器)实现?理想情况下,Rhino适用于Java.在.NET Framework/Mono Framework上运行的可靠Rhino端口将是完美的.
我只看过一些提到过的项目,但从来没有看到过任何我能够运行脚本的东西.这是我已经知道的:
MSScriptControl ActiveX控件:AFAIK,这是Microsoft最后一个真正符合ECMAScript标准的实现(运行JScript 5.7).我已经与MSScriptControl集成,但不认为COM互操作是这个问题的答案.x64是此选项的杀手锏.
JScript.NET:我不算JScript.NET,因为它永远无法成功解析我的任何真实脚本.闭包似乎有问题.
管理JScript:听起来像我想要的但它似乎死在水中.这是DLR的一个主要示例实现,但后来与SilverLight纠缠在一起,并且自2007年以来似乎已经逐渐消失.有关此状态的可信来源将是有帮助的.
MyJScript:作为DLR的教程实现而构建.有人知道这是一个完整的实现吗?
Jint:.NET的JavaScript解释器.不支持Currying或try- catch- finally.
RemObjects Script for .NET:一个有趣的竞争者仍在开发中.我对他们的营销实际上是什么感到困惑,但听起来它最终可能是合适的.如果有人知道更多有关它也会有所帮助.
V8 for .NET:如果有人将V8移植到.NET,这将是很好的.据我所知,这方面也没有太大的努力.链接是一个从托管C++包装器调用它的想法.
对于后台,我希望能够在.NET中执行JavaScript; 即将一组脚本加载到上下文中并调用该上下文并检索执行结果.目前,我通过繁琐的COM Interop跳过箍使用MSScriptControl.COM的不一致使得部署和确保一致的执行非常困难.
我希望能够从.NET中执行相当复杂的JavaScript测试工具.这不是用于创建用户宏或简单的小脚本; 我需要像Rhino这样的真实JavaScript环境.如果实现是在CLR(而不是COM)之上运行的,那么这对当前的一些问题确实有帮助.
在泛型FAQ中:最佳实践说:
编译器将允许您将泛型类型参数显式转换为任何接口,但不能转发给类:
interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass<T>
{
void SomeMethod(T t)
{
ISomeInterface obj1 = (ISomeInterface)t;//Compiles
SomeClass obj2 = (SomeClass)t; //Does not compile
}
}
Run Code Online (Sandbox Code Playgroud)
除非未将类/接口指定为约束类型,否则我认为类和接口的限制都是合理的.
那么为什么这样的行为,为什么它被允许接口呢?
我有一个关于Value类型中的类型构造函数的问题.这个问题的灵感来自Jeffrey Richter在CLR中通过C#3rd ed编写的内容,他说(在第195页 - 第8章)你不应该在值类型中实际定义类型构造函数,因为有时候CLR不会调用它.
所以,例如(好吧......实际上是Jeffrey Richters的例子),即使通过查看IL,我也无法解决为什么在以下代码中没有调用类型构造函数:
internal struct SomeValType
{
static SomeValType()
{
Console.WriteLine("This never gets displayed");
}
public Int32 _x;
}
public sealed class Program
{
static void Main(string[] args)
{
SomeValType[] a = new SomeValType[10];
a[0]._x = 123;
Console.WriteLine(a[0]._x); //Displays 123
}
}
Run Code Online (Sandbox Code Playgroud)
因此,对类型构造函数应用以下规则,我只是看不出为什么根本没有调用上面的值类型构造函数.
所以......我无法理解为什么我看不到这个类型的数组正在被构造.
我最好的猜测是它可能是:
最佳实践等帮助,我只是对它非常感兴趣,因为我希望能够亲眼看到它为什么不被调用.
编辑:我在下面添加了我自己的问题的答案,只是引用杰弗里里希特所说的.
如果有人有任何想法,那将是辉煌的.非常感谢,詹姆斯
我在应用程序中观察到了很多"堆栈内省"代码,这些代码通常隐含地依赖于它们的包含方法没有内联的正确性.这些方法通常涉及到:
MethodBase.GetCurrentMethodAssembly.GetCallingAssemblyAssembly.GetExecutingAssembly现在,我发现围绕这些方法的信息非常混乱.我听说运行时不会内联调用GetCurrentMethod的方法,但我找不到任何相关的文档.我曾多次在StackOverflow上看过帖子,比如这个帖子,表明CLR没有内联交叉汇编调用,但GetCallingAssembly 文档强烈指出不是这样.
还有备受诟病的人[MethodImpl(MethodImplOptions.NoInlining)],但我不确定CLR是否认为这是"请求"或"命令".
请注意,我要求从合同的角度来概述资格,而不是当前JITter的实施由于实施困难而拒绝考虑方法,或者JITter最终在评估交易后最终选择内联合格方法时权衡.我已经阅读了这个和这个,但他们似乎更关注最后两点(有传递提到的MethodImpOptions.NoInlining和"异国情调的IL指令",但这些似乎是作为启发而不是义务呈现).
什么时候CLR 允许内联?