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

So the type returned by the activator (not shown here) is just the POCO I created. There is nothing special about this. But even though the return type GetWrapper

or GetWrapper<T>

return object is of type dynamic, so none of the properties of the returned actual class are considered intellisense. Any ideas?

enter image description here

UPDATE: Sorry John:

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);
}

      

+2


source to share


1 answer


I strongly suspect that either child1

or child1.kind

is of a type dynamic

, which means that the expression is considered a dynamically linked expression in spite of 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
    }
}

      

Invalid operator is not valid because type c

is equal string

- but subsequent operator is fine because type d

is equal dynamic

.

Even though there is only one possible method that it can be bound to at runtime - and even if that binding will always work, the basic rule is that almost any expression that includes a value dynamic

is considered a type dynamic

. (There are a few exceptions such as as

and new

.)



To make the return value non-dynamic, just put your values ​​in object

:

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

      

This will now be a statically linked call. Or you can leave it as a dynamically linked call and use an implicit conversion from type expression dynamic

to other types:

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

      

+5


source







All Articles