Question

My goal is to be able to use intellisense, while still instructing the compiler to generate late-binding code (i.e. CallSites and Binders).

Say I have

class MyDynamicDataProvider
{
   public int Data{get;set}
}

I want to write:

MyDynamicDataProvider provider = new MyDynamicDataProvider();
int x = provider.Data;

I want the Data property call to be late-bound. Yet currently, if I don't declare the provider variable as dynamic, the compiler will pre-bound the call. i.e. in runtime, the value stored in the property's backing field will be returned.

At the same time, I want the intelllisense while coding, which means that I should declare the provider using the appropriate type.

Is there any way of acheiving both ends simultanously (using static declarations for intellisense, while relying on dynamic binding during runtime)?

Edit 1: One might wonder why not just use the getter to perform whatever logic I need. The thing is that I'm trying to develop some meta-classes, which would allow developers to just define classes and properties, use getters, setters, methods, etc., while the magic is happening by dynamic means. There would be many such types, and I'd like to avoid such redundant code in the classes themselves.

Edit 2: It would be the nice if I could declare a class with an attribute which tells the compiler to late bound all calls to members of it.

Was it helpful?

Solution

It seems you don't actually want dynamic, you just want to dynamically implement the functionality for statically defined properties and methods. If that's the case, you can create the classes as abstract and then dynamically implement them.

There is several ways to do that. Either directly using Reflection.Emit, or CodeDOM to generate classes that inherit from the abstract ones. Or you could use a tool that makes this much easier (and usually somewhat slower), like Castle DynamicProxy.

OTHER TIPS

Visual Studio can't provide intellisense on a late-bound object since it it has no idea whether or not the member actually "exists". It might be possible for Visual Studio to provide this out of the box - but it doesn't. The default intellisense just shuts off on a dynamic. There are two solutions:

  1. If you know the member you want to call, why are you trying to use late-binding at all?
  2. Some products like Resharper provide pseudo intellisense by statically looking for late-bound calls that have been made else where. In the image below, it provides intellisense for Hello because there is code elsewhere making that call. It's clever, but it isn't foolproof either.

Resharper

To do that, your best option is to implement Data so it does what you want dynamically, possibly using a facade.

If we assume you somehow have a MyDynamicDataProvider, that knows what to do when it is called as Dynamic - then you could use a statically typed facade like this:

 class DataProviderFacade 
 { 
     private dynamic inner;
     public DataProviderFacade(dynamic inner)
     {
         this.inner = inner;
     }

     public int Data { get { return inner.Data; } }
 }

That being said, I can't imagine why you would need this.

If you use the open source ImpromptuInterface (via nuget) you can define static interfaces and then it will emit and cache dynamic binding code (callsites and binders) matching that interface's members. You just use a single generic extension method on object called ActLike and it will statically return that interface and actually return an emitted proxy that implements that interface and is forwarding calls via c# dynamic binding (so it will work with static and dynamic objects a like).

After the one time generation of the proxy the performance cost for invoking a method is just one static invocation + one dynamic invocation.

public interface IMyDynamicDataProvider
{
   int Data{get;set}
}

...

IMyDynamicDataProviderprovider = new MyDynamicDataProvider().ActLike<IMyDynamicDataProvider>();
int x = provider.Data;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top