Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 类型引用的实际应用_C#_.net_Typedreference - Fatal编程技术网

C# 类型引用的实际应用

C# 类型引用的实际应用,c#,.net,typedreference,C#,.net,Typedreference,在实际代码中是否会实际使用该结构 编辑:.Net framework在控制台.WriteLine和字符串.Concat的重载中使用它们,它们从\uu arglist参数构建数组,并将其传递给正常的参数重载。为什么会存在这些重载 TypedReference结构是否有实际的用途,您会在实际代码中使用它 对。如果我需要与C型变量方法的互操作性,我会使用它们 为什么会存在这些重载 它们的存在是为了与喜欢使用C型变量方法的调用方进行互操作。这似乎是一个非常古老的问题,但我想再添加一个用例:当您有一个结构

在实际代码中是否会实际使用该结构

编辑:.Net framework在
控制台.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。