>问题
当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)
将在plugin
类型时'object' does not contain a definition for 'Add'
消息System.Reflection.TargetInvocationException
System.ComponentModel.Composition.ExportServices.DisposableLazy<IPlugin,IMetadata>
但是当plugin
类型时,它完全完美
System.Lazy<IPlugin, IMetadata>
当反射用于在实例filteredPlugins
实例上调用Add
方法时,就像在下一行中所做的那样 - 对于任何类型,一切都很好。
我的问题是为什么在DisposableLazy
类型的情况下找不到Add
方法。
背景
此代码是我在该方法中使用的方法的一部分OnImportsSatisfied()
。我正在使用两种导入 - 仅在RequiredCreationPolicy
上有所不同 - 在具有CreationPolicy.NonShared
和另一个默认值CreationPolicy.Any
上。
[ImportMany(RequiredCreationPolicy = CreationPolicy.NonShared)]
private IEnumerable<Lazy<IPlugin, IMetadata>> plugins = null;
对于CreationPolicy.NonShared
字段,plugins
中的底图类型DisposableLazy
,对于CreationPolicy.Any
,plugins
中的底图类型Lazy
。
编辑:正如答案中所问的 - 我正在使用dynamic
变量,因为每次调用此方法时IPlugin
接口都可以更改,并且它们不必有任何共同点。
Edit2:我刚刚发现了类似的问题 C# 动态类型陷阱,所以这可能可以作为重复内容关闭。
因为 System.ComponentModel.Composition.ExportServices.DisposableLazy
是一个private
类,所以运行时绑定器很难相信你有权使用类型,而反射并不关心。
这就引出了一个问题,在这种情况下,为什么要使用动态。 既然DisposableLazy<IPlugin,IMetadata>
公共接口是它的子类Lazy<IPlugin, IMetadata>
和IDisposable
,你不应该只使用List<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);
}
}