C# 类型引用的实际应用
在实际代码中是否会实际使用该结构 编辑:.Net framework在C# 类型引用的实际应用,c#,.net,typedreference,C#,.net,Typedreference,在实际代码中是否会实际使用该结构 编辑:.Net framework在控制台.WriteLine和字符串.Concat的重载中使用它们,它们从\uu arglist参数构建数组,并将其传递给正常的参数重载。为什么会存在这些重载 TypedReference结构是否有实际的用途,您会在实际代码中使用它 对。如果我需要与C型变量方法的互操作性,我会使用它们 为什么会存在这些重载 它们的存在是为了与喜欢使用C型变量方法的调用方进行互操作。这似乎是一个非常古老的问题,但我想再添加一个用例:当您有一个结构
控制台.WriteLine
和字符串.Concat
的重载中使用它们,它们从\uu arglist
参数构建数组,并将其传递给正常的参数
重载。为什么会存在这些重载
TypedReference结构是否有实际的用途,您会在实际代码中使用它
对。如果我需要与C型变量方法的互操作性,我会使用它们
为什么会存在这些重载
它们的存在是为了与喜欢使用C型变量方法的调用方进行互操作。这似乎是一个非常古老的问题,但我想再添加一个用例:当您有一个结构并希望通过反射设置其变量时,您将始终对装箱值进行操作,而不会更改原始值。这是没有用的:
TestFields fields = new TestFields { MaxValue = 1234 };
FieldInfo info = typeof(TestFields).GetField("MaxValue");
info.SetValue(fields, 4096);
// result: fields.MaxValue is still 1234!!
这可以通过隐含的装箱来补救,但这样就失去了类型安全性。相反,您可以使用TypedParameter
解决此问题:
TestFields fields = new TestFields { MaxValue = 1234 };
FieldInfo info = fields.GetType().GetField("MaxValue");
TypedReference reference = __makeref(fields);
info.SetValueDirect(reference, 4096);
// result: fields.MaxValue is now indeed 4096!!
+1感谢你没有抨击C风格的变量位:)这里希望你能在5.0之前拥有变量模板(不是泛型)。我不知道我是否会称之为反射特定的问题
SetValue
将对象作为输入,因此任何值类型都将被装箱以匹配该方法的签名。@BrianRasmussen:afaik,此反射特定行为源于反射早于泛型,否则将不需要装箱。在(预)装箱的值类型和引用上,不会出现此问题。我的观点是,任何将对象
作为输入的方法(在您的示例中,SetValue
的第一个重载就是这样做的)都会强制装箱值。这就是统一类型系统处理值的方式。是的,然后系统引入了ref
来处理值引用,但是SetXXX没有ref重载。事实上,系统是这样设计的,这不是他们添加SetValueDirect
并因此引入一个对象的唯一原因吗?为什么这不是建设性的还可以使用它传递堆栈位置/变量引用(例如,传递给其他线程或从方法返回)。它需要不安全的代码和“复制”类型引用作为两个IntPtr。