var บอกเป็นนัยว่ามีการใช้การตรวจสอบชนิดคงที่ (การรวมก่อนหน้า) แบบไดนามิกหมายถึงว่ามีการใช้การตรวจสอบประเภทแบบไดนามิก (การรวมภายหลัง) ในแง่ของรหัสให้พิจารณาสิ่งต่อไปนี้:
class Junk
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
class Program
{
static void Main(String[] args)
{
var a = new Junk();
dynamic b = new Junk();
a.Hello();
b.Hello();
}
}
หากคุณรวบรวมและตรวจสอบผลลัพธ์ด้วย ILSpy คุณจะพบว่าคอมไพเลอร์ได้เพิ่มรหัสการเชื่อมโยงบางส่วนซึ่งจะจัดการการโทรไปยัง Hello () จาก b ในขณะที่การรวมก่อนหน้านี้ถูกใช้กับ a, a สามารถโทร Hello ได้ () โดยตรง
เช่น (การถอดแยกชิ้นส่วน ILSpy)
using System;
namespace ConsoleApplication1
{
internal class Junk
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
}
using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication1
{
internal class Program
{
[CompilerGenerated]
private static class <Main>o__SiteContainer0
{
public static CallSite<Action<CallSite, object>> <>p__Site1;
}
private static void Main(string[] args)
{
Junk a = new Junk(); //NOTE: Compiler converted var to Junk
object b = new Junk(); //NOTE: Compiler converted dynamic to object
a.Hello(); //Already Junk so just call the method.
//NOTE: Runtime binding (late binding) implementation added by compiler.
if (Program.<Main>o__SiteContainer0.<>p__Site1 == null)
{
Program.<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Hello", null, typeof(Program), new CSharpArgumentInfo[]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}));
}
Program.<Main>o__SiteContainer0.<>p__Site1.Target(Program.<Main>o__SiteContainer0.<>p__Site1, b);
}
}
}
สิ่งที่ดีที่สุดที่คุณสามารถทำได้เพื่อค้นหาความแตกต่างคือการเขียนแอปคอนโซลตัวเล็ก ๆ เช่นนี้และทดสอบด้วยตัวเองด้วย ILSpy