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

為{幸葍}努か 提交于 2019-12-11 03:43:09

问题


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?

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

回答1:


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


来源:https://stackoverflow.com/questions/25586520/why-does-this-method-keep-returning-dynamic-despite-the-return-type-in-the-signa

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!