Mar*_*tin 3 c# garbage-collection
我有一个像这样的结构
struct MyStructure
:IFoo
{
}
Run Code Online (Sandbox Code Playgroud)
和这样的方法:
public BarThisFoo(IFoo a)
{
}
Run Code Online (Sandbox Code Playgroud)
我的问题是将结构传递给该方法的"框"结构,从而导致垃圾分配?
附录:在有人说之前,垃圾收集在这个应用程序中不是免费的,它实际上对垃圾收集非常敏感,所以免费分配代码很重要.
为了避免装箱你可以使用带有约束的泛型:
struct MyStructure
:IFoo
{
}
public void BarThisFoo<T>(T a) where T : IFoo
{
}
Run Code Online (Sandbox Code Playgroud)
请参阅J. Richter CLR via C#,2nd edition,chapter 14:Interfaces,section about Generics and Interface Constraints.
编辑:
示例代码
using System;
using System.Collections;
interface IFoo {
void Foo();
}
struct MyStructure : IFoo {
public void Foo() {
}
}
public static class Program {
static void BarThisFoo<T>(T t) where T : IFoo {
t.Foo();
}
static void Main(string[] args) {
MyStructure s = new MyStructure();
BarThisFoo(s);
}
}
Run Code Online (Sandbox Code Playgroud)
方法Main的IL代码不包含任何框指令:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 15 (0xf)
.maxstack 1
.locals init ([0] valuetype MyStructure s)
IL_0000: ldloca.s s
IL_0002: initobj MyStructure
IL_0008: ldloc.0
IL_0009: call void Program::BarThisFoo<valuetype MyStructure>(!!0)
IL_000e: ret
} // end of method Program::Main
Run Code Online (Sandbox Code Playgroud)
正如其他人已经注意到的那样,是的,将结构体转换为它实现的界面是拳击模型.更重要的不是问题的答案,而是你能够自己回答.如果使用ILDASM反汇编测试应用程序,您将看到编译器在转换时生成"box"指令.现在下次你有关于拳击的问题,你可以自己写一个测试程序,反汇编,然后你就会知道.
顺便提一下,请注意,如果在结构上的隐式实现的接口方法上调用方法,则不会发生装箱:
struct S : IFoo { public void Foo() { ...
...
myS.Foo(); // no boxing
((IFoo)myS).Foo(); // boxing
Run Code Online (Sandbox Code Playgroud)
这与可变值类型的接口方法特别相关; 请记住,如果您正在改变盒装值类型,那么您正在改变框中的值,而不是最初包含盒装值的变量.myS.Foo()和((IFoo)myS).Foo()可以有不同的语义这一事实是可变值类型纯粹是邪恶的另一个原因,应该避免.
| 归档时间: |
|
| 查看次数: |
560 次 |
| 最近记录: |