1

问题

当在变量Add上调用方法时,我使用动态创建的项目列表遇到问题。dynamic考虑以下代码。

IEnumerable<dynamic> plugins = (IEnumerable<dynamic>)field.GetValue(instance);
if (plugins == null)
  continue;

dynamic filteredPlugins = null;
foreach (var plugin in plugins)
{
  if (filteredPlugins == null)
  filteredPlugins = Activator
    .CreateInstance(typeof(List<>)
    .MakeGenericType(plugin.GetType()));

if (/* this condition does not matter*/)
  //filteredPlugins.Add(plugin);
  filteredPlugins.GetType().GetMethod("Add")
    .Invoke(filteredPlugins, new object[] { plugin });
}

现在,注释行将与消息一起filteredPlugins.Add(plugin)抛出when is of typeSystem.Reflection.TargetInvocationException'object' does not contain a definition for 'Add'plugin

System.ComponentModel.Composition.ExportServices.DisposableLazy<IPlugin,IMetadata>

但是当plugin是类型时它完全完美

System.Lazy<IPlugin, IMetadata>

当反射用于调用Add实例实例上的方法时,filteredPlugins就像在下一行中所做的那样 - 一切都适用于任何类型。

我的问题是为什么Add在类型的情况下找不到方法DisposableLazy

背景

这段代码是我在方法中使用的OnImportsSatisfied()方法的一部分。我正在使用两种类型的导入 - 仅在RequiredCreationPolicy- on hasCreationPolicy.NonShared和其他默认值CreationPolicy.Any.

[ImportMany(RequiredCreationPolicy = CreationPolicy.NonShared)]
private IEnumerable<Lazy<IPlugin, IMetadata>> plugins = null;

对于is 中的底层类型和is中的底层类型的CreationPolicy.NonShared字段。pluginsDisposableLazyCreationPolicy.AnypluginsLazy

编辑:如答案中所问 - 我正在使用dynamic变量,因为IPlugin接口可以在每次调用此方法时更改,并且它们不必有任何共同点。

Edit2:我刚刚发现了类似的问题C# dynamic type gotcha,所以这可能会被关闭为重复。

4

1 回答 1

2

因为System.ComponentModel.Composition.ExportServices.DisposableLazy是一个private类,运行时绑定器无法相信您有权使用类型,而反射并不关心。

这就引出了一个问题,在这种情况下你为什么要使用动力学。由于DisposableLazy<IPlugin,IMetadata>公共接口是它的子类Lazy<IPlugin, IMetadata>& IDisposable,你不应该只使用 aList<Lazy<IPlugin, IMetadata>>来处理这两种情况吗?

var plugins = (IEnumerable<Lazy<IPlugin, IMetadata>>)field.GetValue(instance);
if (plugins == null)
  continue;

var filteredPlugins = new List<Lazy<IPlugin, IMetadata>>();
foreach (var plugin in plugins)
{
  if (/* this condition does not matter*/)
     filteredPlugins.Add(plugin);
  }
}
于 2013-06-05T18:56:37.813 回答