0

我的目标是能够使用智能感知,同时仍然指示编译器生成后期绑定代码(即 CallSites 和 Binder)。

说我有

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

我想写:

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

我希望 Data 属性调用是后期绑定的。然而目前,如果我不将provider变量声明为动态的,编译器将预先绑定调用。即在运行时,将返回存储在属性的支持字段中的值。

同时,我想要在编码时进行智能感知,这意味着我应该使用适当的类型声明提供程序。

有没有办法同时实现两端(使用静态声明进行智能感知,同时在运行时依赖动态绑定)?

编辑 1:有人可能想知道为什么不只使用 getter 来执行我需要的任何逻辑。问题是我正在尝试开发一些元类,这将允许开发人员只定义类和属性,使用 getter、setter、方法等,而神奇的是通过动态方式发生的。会有很多这样的类型,我想在类本身中避免这样的冗余代码。

编辑2:如果我可以声明一个具有属性的类,该属性告诉编译器延迟绑定对其成员的所有调用,那就太好了。

4

4 回答 4

2

Visual Studio 无法在后期绑定对象上提供智能感知,因为它不知道该成员是否实际“存在”。Visual Studio可能会开箱即用地提供此功能 - 但事实并非如此。默认的智能感知只是关闭动态。有两种解决方案:

  1. 如果您知道要呼叫的成员,您为什么要尝试使用后期绑定?
  2. 像Resharper这样的一些产品通过静态查找在其他地方进行的后期绑定调用来提供伪智能感知。在下图中,它提供了智能感知,Hello因为其他地方有代码进行该调用。它很聪明,但也不是万无一失的。

锐器

于 2011-09-02T17:54:09.170 回答
1

为此,您最好的选择是实现Data它以便动态地执行您想要的操作,可能使用外观。

如果我们假设您以某种方式拥有一个 MyDynamicDataProvider,它知道当它被称为 Dynamic 时该做什么 - 那么您可以使用这样的静态类型外观:

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

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

话虽如此,我无法想象你为什么需要这个。

于 2011-09-02T17:47:37.017 回答
0

看来您实际上并不想要dynamic,您只想动态实现静态定义的属性和方法的功能。如果是这种情况,您可以将类创建为抽象类,然后动态实现它们。

有几种方法可以做到这一点。直接使用 Reflection.Emit 或 CodeDOM 来生成继承自抽象类的类。或者,您可以使用使这更容易(并且通常更慢)的工具,例如Castle DynamicProxy

于 2011-09-02T19:01:51.540 回答
0

如果您使用开源 ImpromptuInterface(通过 nuget),您可以定义静态接口,然后它将发出并缓存与该接口成员匹配的动态绑定代码(调用站点和绑定器)。您只需在名为ActLike的对象上使用单个通用扩展方法,它将静态返回该接口并实际返回实现该接口并通过 c# 动态绑定转发调用的发出代理(因此它将与静态和动态对象一起使用) .

在代理生成一次之后,调用方法的性能成本只是一次静态调用 + 一次动态调用。

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

...

IMyDynamicDataProviderprovider = new MyDynamicDataProvider().ActLike<IMyDynamicDataProvider>();
int x = provider.Data;
于 2011-09-07T15:05:38.360 回答