Why does this method keep returning dynamic despite the return type in the signature?

So the type being returned by the activator (not shown here) is just a POCO that I created. Nothing special about it at all. But despite, the return type of GetWrapper or GetWrapper<T> the object being returned is of type dynamic so none of the properties of the actual class being return are being seen by intellisense. Any ideas?

enter image description here

UPDATE: Sorry, Jon:

public static T GetWrapper<T>(object type, dynamic obj)
   where T : class, IRedditObject
{
    return GetWrapper(type, obj) as T;
}

public static object GetWrapper(object type, dynamic obj)
{
    return Activator.CreateInstance(Types[type.ToString()], obj);
}

public class LinkWrapper : IRedditObject
{
    private readonly dynamic _link;

    public string Kind { get { return "t3"; } }
    public dynamic Data { get { return _link.data; } }

    public LinkWrapper(dynamic link)
    {
        _link = link;
    }

    public string Domain { get { return Data.domain; } }
}

[TestMethod]
public void Test()
{
    var proxy = new SubredditProxy();
    var dotnet = proxy.GetSubredditAsync("dotnet").Result;

    var child1 = dotnet.data.children[0];

    // this is being returned as dynamic
    var obj = RedditDynamicObjectWrapperFactory.GetWrapper<LinkWrapper>(child1.kind, child1);


    Assert.IsNotNull(obj);
}
Jon Skeet
people
quotationmark

I strongly suspect that either child1 or child1.kind are of type dynamic, meaning that the expression is deemed to be a dynamically-bound expression, despite everything else.

Here's a short but complete example to demonstrate what I mean:

using System;

class Test
{
    public static T Foo<T>(object x)
    {
       return default(T);
    }

    public static void Main(string[] args)
    {
        object a = new object();
        dynamic b = a;

        var c = Foo<string>(a);
        var d = Foo<string>(b);

        Console.WriteLine(c.SomeRandomMember); // Invalid
        Console.WriteLine(d.SomeRandomMember); // Valid
    }
}

The invalid statement is invalid because the type of c is string - but the subsequent statement is fine, because the type of d is dynamic.

Even though there's only one possible method which it could be bound to at execution time - and even though that binding will always work - the basic rule is that almost any expression involving a dynamic value is deemed to be of type dynamic. (There are a few exceptions such as as and new.)

To make your return value non-dynamic, just cast your values to object:

var obj = RedditDynamicObjectWrapperFactory.GetWrapper<LinkWrapper>
     ((object) child1.kind, (object) child1);

That will now be a statically bound call. Or you could leave it as a dynamically bound call, and use the implicit conversion from an expression of type dynamic to other types:

LinkWrapper obj = RedditDynamicObjectWrapperFactory.GetWrapper<LinkWrapper>(child1.kind, child1);

people

See more on this question at Stackoverflow