请帮助我们解决"几乎"的争议一切都是一个对象(Stack Overflow问题的答案作为一个新手,在学习C#之前有什么我应该注意的吗?).我认为就是这种情况,因为Visual Studio中的所有内容至少都显示为结构体.请张贴参考文献,以免它变成"现代傻瓜"(This American Life).
请注意,这个问题涉及C#,不一定是.NET,以及它如何处理引擎盖下的数据(显然它都是1和0).
以下是"一切都是对象"的评论:
对象的定义:"对象"作为类System.Object的继承者与"对象"作为类型与"对象"作为引用类型的实例."
这更像是一个'奇怪的原因',而不是一个特定的问题,但请看下面的代码
        static void Main(string[] args)
        {
            int val = 10;
            Console.WriteLine("val is {0}", val); // (1)
            Console.WriteLine("val is {0}", val.ToString()); //(2)
        }
在情况(1)中输出以下IL
IL_0000:  nop
  IL_0001:  ldc.i4.s   10
  IL_0003:  stloc.0
  IL_0004:  ldstr      "val is {0}"
  IL_0009:  ldloc.0
  IL_000a:  box        [mscorlib]System.Int32
  IL_000f:  call       void [mscorlib]System.Console::WriteLine(string,
                                                                object)
在我明确调用toString方法的情况下(2)我得到了
IL_0014:  nop
  IL_0015:  ldstr      "val is {0}"
  IL_001a:  ldloca.s   val
  IL_001c:  call       instance string [mscorlib]System.Int32::ToString()
  IL_0021:  call       void [mscorlib]System.Console::WriteLine(string,
                                                                object)
所以在case(1)中,即使int重写toString,也会将值类型装箱并调用toString方法,这可能会调用vtable覆盖
所以结果完全相同,但显式的toString避免了装箱操作
谁知道为什么?
=编辑= 
确定要清楚,令我感到困惑的是,我开始假设即使int派生自System.ValueType,而System.ValueType又派生自System.Object,因为它包含toString,GetHashCode等.
所以在我的天真view(可能来自C++),如果我重写从System.Object派生的方法,那么就不需要强制转换为System.Object(因此将值类型框),因为存在overriden方法,编译器将自动引用vtable条目对于类型.
我也假设调用Console.WriteLine()隐式调用int.toString所以也许这就是我出错的地方.希望有道理
好的 - 全部排序.谢谢大家直截了当.所有这些都与我的糟糕假设有关,即Console.WriteLine正在进行隐式字符串转换.不要问我为什么这么想 - 看起来很明显现在错误:)
我正在阅读"C#via CLR"和第380页,有一条说明如下:
注意Enum类定义HasFlag方法,定义如下
public Boolean HasFlag(Enum flag);使用此方法,您可以重写对Console.WriteLine的调用,如下所示:
Console.WriteLine("Is {0} hidden? {1}", file, attributes.HasFlag(FileAttributes.Hidden));但是,我建议您出于这个原因避免使用HasFlag方法:
由于它采用了Enum类型的参数,因此传递给它的任何值都必须装箱,需要进行内存分配."
我无法理解这个粗犷的陈述 - 为什么"
您传递给它的任何值都必须装箱
该flag参数的类型是Enum,这是一个值类型,为什么会有拳击?"传递给它的任何值必须装箱"应该意味着当你将值类型传递给参数时会发生装箱Enum flag,对吧?
我正在创建自己的DI框架,创建委托工厂作为学习练习.构建类型委托的方法是使用表达式来创建一个函数,该函数通过引用我的容器和任何构造函数参数来调用静态方法.
这引发了一个关于价值类型的有趣问题.哪个性能最高:
a)使用反射选择具有正确参数数量的静态通用方法,然后使用MakeGenericMethod删除泛型
b)去旧时尚params对象[]并采取拳击击中?
当我在Microsoft MSDN上发现这篇文章时,我正在研究可空的bool
您可以使用C#typeof运算符创建表示Nullable类型的Type对象.
所以我尝试用可空的布尔检查:
Console.Write(typeof(bool?)); //System.Nullable`1[System.Boolean]
MSDN上的文章说
您还可以使用System.Reflection命名空间的类和方法来生成表示Nullable类型的Type对象.但是,如果尝试通过使用GetType方法或is运算符在运行时从Nullable变量获取类型信息,则结果是一个Type对象,它表示基础类型,而不是Nullable类型本身.
在Nullable类型上调用GetType会导致在将类型隐式转换为Object时执行装箱操作.因此,GetType始终返回表示基础类型的Type对象,而不是Nullable类型.
如果这是真的,我希望得到相同的结果,.GetType()无论我使用可空的bool还是常规的bool.但这不是发生的事情:
    bool a = new bool();
    Console.Write(a.GetType()); //Prints System.Boolean
    bool? b = new bool?();
    Console.Write(b.GetType()); //Exception!
发生的例外情况:
BoolTest.exe中出现未处理的"System.NullReferenceException"类型异常
附加信息:未将对象引用设置为对象的实例.
但是对象引用设置为对象的实例.可能是导致此错误的原因是什么?