Reputation: 12192
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);
}
Upvotes: 4
Views: 842
Reputation: 1484
I agree with the current answer (https://stackoverflow.com/a/25586620/1942762) but here is the explanation from the the C# programming guide (Overload resolution with arguments of type dynamic):
Overload resolution occurs at run time instead of at compile time if one or more of the arguments in a method call have the type dynamic, or if the receiver of the method call is of type dynamic.
Your parameter is probably of type dynamic so your IDE will consider obj
as a dynamic too
Upvotes: 0
Reputation: 1500635
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);
Upvotes: 8