【发布时间】:2018-08-02 10:24:38
【问题描述】:
那么这里发生了什么?
这是背景故事。我正在尝试将 .net 标准库集成到 .net 框架产品中。此 .net 框架产品使用旧的 Microsoft.Practices 框架,该框架使用 ObjectBuilder 作为服务容器。
现代 IoC 容器可以做的一件事是 ObjectBuilder 无法做到的,那就是处理同一服务类型的多个实现,并在请求时注入该服务类型的 IEnumerable
ObjectBuilder 在 Microsoft.Practices 的 WebClientSoftwareFactory 中使用时,使用 IL 为容器构造对象并将依赖项注入属性。所以即使你添加了一个单例实例,它仍然会尝试使用 IL 注入到实例的属性中。
尝试将 .Net 标准类型的 List
这是在 .net framework 4.7.2 上运行的控制台应用程序
namespace ILTest
{
class Program
{
delegate string Echo(string value);
static void Main(string[] args)
{
Console.WindowWidth = Console.WindowWidth * 2;
EchoOn("1324");
EchoOn(new List<string>());
EchoOn(new NetStandardType());
EchoOn(new List<NetStandardType>()); // this line fails
EchoOn(new GenericNetStandardType<string>());
EchoOn(new GenericNetStandardType<NetStandardType>());
Console.ReadLine();
}
static void EchoOn<T>(T obj)
{
var type = typeof(T);
var value = Guid.NewGuid().ToString();
var echo = CreateEchoMethodOn(obj);
try
{
var echoed = echo(value);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Successful il on {type.FullName}");
}
catch(Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Failed il on {type.FullName}");
Console.WriteLine(ex);
}
}
static Echo CreateEchoMethodOn(object obj)
{
var type = obj.GetType();
var method = new DynamicMethod($"Echo_{type.FullName}", typeof(string), new[] { typeof(string) }, type);
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ret);
return (Echo)method.CreateDelegate(typeof(Echo));
}
}
}
这些是 .net 标准 2.0 库中的类
namespace StandardLib
{
public class NetStandardType
{
}
public class GenericNetStandardType<T>
{
}
}
除了 List
- 字符串
- .net 框架类型
- DynamicMethod 成功
- 列表
- .net 框架泛型类型
- .net 框架通用参数
- DynamicMethod 成功
- 网络标准类型
- .net 标准类型
- DynamicMethod 成功
- 列表
- .net 框架泛型类型
- .net 标准泛型参数
- DynamicMethod 失败
- GenericNetStandardType
- .net 标准泛型类型
- .net 框架通用参数
- DynamicMethod 成功
- GenericNetStandardType
- .net 标准泛型类型
- .net 标准泛型参数
- DynamicMethod 成功
那么,再次,这里发生了什么?是不是DynamicMethod in.net framework的bug?
【问题讨论】:
-
我可以用你分享的代码重现这个。但是,我也能够使用来自与应用程序相同的程序集的类型来重现它。这看起来不像是 .NET Standard 的特定问题。我能够通过将 List
替换为 Hashset 来完成这项工作,因此 List 有一些特别之处。我将深入挖掘,看看我是否能弄清楚 List 有什么特别之处会阻止它工作。
标签: c# .net generics dynamic .net-standard-2.0