Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the practical difference between dynamic and T in C#

I read about Type dynamic in C# 2010. (the corresponding msdn entry)

I am confused about the practical difference between T and dynamic while developing generic functions. My current tests didn't show new ways to use dynamica way, that isn't possible with T. In addition it seems, that dynamic needs much more time in runtime to achieve the same tasks.

Some example code to make my point clear:

// Sample Object
public class SampleObj
{
    public string Test { get; set; }
}

My Test-Method (measuring speed as well):

static void Main(string[] args)
{
    var sampleObj1 = new SampleObj { Test = "Test1" };
    var sampleObj2 = new SampleObj { Test = "Test2" };

    Stopwatch c1 = Stopwatch.StartNew();
    bool res1 = CompareObjectsT<SampleObj>(sampleObj1, sampleObj2);
    c1.Stop();
    Console.WriteLine("Comparison T: {0} time: {1} ms", res1, c1.ElapsedMilliseconds);


    Stopwatch c2 = Stopwatch.StartNew();
    bool res2 = CompareObjectsDyna(sampleObj1, sampleObj2);
    Console.WriteLine("Comparison dynamic: {0} time: {1} ms", res2, c2.ElapsedMilliseconds);
    c2.Stop();

    var instance = new X<SampleObj>();

    Console.ReadLine();
}

The result is:

Comparison T: False time: 6 ms
Comparison dynamic: False time: 3969 ms

The dynamic functions needs much more time, compared to the T comparison.

Decompiling my test application reveals heavy usage of reflection which may lead to this huge amount of time:

private static bool CompareObjectsDyna([Dynamic] object source1, [Dynamic] object source2)
{
    if (<CompareObjectsDyna>o__SiteContainer2.<>p__Site3 == null)
    {
        <CompareObjectsDyna>o__SiteContainer2.<>p__Site3 = CallSite<Func<CallSite, object, bool>>.Create(Binder.Convert(CSharpBinderFlags.None, typeof(bool), typeof(Program)));
    }
    if (<CompareObjectsDyna>o__SiteContainer2.<>p__Site4 == null)
    {
        <CompareObjectsDyna>o__SiteContainer2.<>p__Site4 = CallSite<Func<CallSite, Type, object, object, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.None, "Equals", null, typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
    }
    return <CompareObjectsDyna>o__SiteContainer2.<>p__Site3.Target(<CompareObjectsDyna>o__SiteContainer2.<>p__Site3, <CompareObjectsDyna>o__SiteContainer2.<>p__Site4.Target(<CompareObjectsDyna>o__SiteContainer2.<>p__Site4, typeof(object), source1, source2));
}

I considered this post but this hasn't ansered my question.

Can someone tell me, in what scenario dynamic is much more effective than T? (hopefully with a small practical sample)

like image 796
Dennis Alexander Avatar asked Feb 11 '13 11:02

Dennis Alexander


1 Answers

Short answer is that generic type T must be known at compile time, but dynamic is inferred at runtime.

like image 121
Hamlet Hakobyan Avatar answered Oct 20 '22 00:10

Hamlet Hakobyan