- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
这有点啰嗦,所以这里是快速版本:
为什么这会导致运行时 TypeLoadException?(编译器应该阻止我这样做吗?)
interface I
{
void Foo<T>();
}
class C<T1>
{
public void Foo<T2>() where T2 : T1 { }
}
class D : C<System.Object>, I { }
如果您尝试实例化 D,则会发生异常。
更长、更具探索性的版本:
考虑:
interface I
{
void Foo<T>();
}
class C<T1>
{
public void Foo<T2>() where T2 : T1 { }
}
class some_other_class { }
class D : C<some_other_class>, I { } // compiler error CS0425
这是非法的,因为 C.Foo()
上的类型限制与 I.Foo()
上的不匹配.它会生成编译器错误 CS0425。
但我认为我可以打破规则:
class D : C<System.Object>, I { } // yep, it compiles
通过使用 Object
作为对 T2 的约束,我否定该约束。我可以安全地将任何类型传递给 D.Foo<T>()
,因为一切都源自 Object
.
即便如此,我仍然预计会出现编译错误。在 C# 语言 意义上,它违反了“C.Foo() 上的约束必须与 I.Foo() 上的约束相匹配”的规则,我认为编译器会坚持规则。但它确实编译。似乎编译器看到了我在做什么,理解它是安全的,并且视而不见。
我以为我已经成功了,但运行时说没那么快。如果我尝试创建 D
的实例,我得到一个 TypeLoadException:“类型 'D' 上的方法 'C`1.Foo' 试图隐式实现具有较弱类型参数约束的接口(interface)方法。”
但是这个错误在技术上不是错误的吗?不使用 Object
对于 C<T1>
取消对 C.Foo()
的约束,从而使其等同于 - 不强于 - I.Foo()
?编译器似乎同意,但运行时不同意。
为了证明我的观点,我将其简化为 D
不等式:
interface I<T1>
{
void Foo<T2>() where T2 : T1;
}
class some_other_class { }
class C : I<some_other_class> // compiler error CS0425
{
public void Foo<T>() { }
}
但是:
class C : I<Object> // compiles
{
public void Foo<T>() { }
}
对于传递给 Foo<T>()
的任何类型,这都能完美地编译和运行.
为什么?运行时是否存在错误,或者(更有可能)是否存在我没有看到的此异常的原因 - 在这种情况下,编译器不应该阻止我吗?
有趣的是,如果通过将约束从类移动到接口(interface)来反转场景...
interface I<T1>
{
void Foo<T2>() where T2 : T1;
}
class C
{
public void Foo<T>() { }
}
class some_other_class { }
class D : C, I<some_other_class> { } // compiler error CS0425, as expected
我再次否定约束:
class D : C, I<System.Object> { } // compiles
这次运行正常!
D d := new D();
d.Foo<Int32>();
d.Foo<String>();
d.Foo<Enum>();
d.Foo<IAppDomainSetup>();
d.Foo<InvalidCastException>();
任何事情都会发生,这对我来说非常有意义。 (等式中有或没有 D
都一样)
那么为什么第一种方式会中断?
附录:
我忘了补充一点,TypeLoadException 有一个简单的解决方法:
interface I
{
void Foo<T>();
}
class C<T1>
{
public void Foo<T2>() where T2 : T1 { }
}
class D : C<Object>, I
{
void I.Foo<T>()
{
Foo<T>();
}
}
明确实现I.Foo()
很好。只有隐式实现会导致 TypeLoadException。现在我可以这样做了:
I d = new D();
d.Foo<any_type_i_like>();
但这仍然是一个特例。尝试使用除 System.Object 之外的任何其他内容,这将无法编译。我觉得这样做有点脏,因为我不确定它是否故意以这种方式工作。
最佳答案
这是一个错误 - 请参阅 Implementing Generic Method From Generic Interface Causes TypeLoadException和 Unverifiable Code with Generic Interface and Generic Method with Type Parameter Constraint .不过,我不清楚这是 C# 错误还是 CLR 错误。
[由 OP 添加:]
这是 Microsoft 在您链接到的第二个线程中所说的(我强调的):
There is a mismatch between the algorithms used by the runtime and the C# compiler to determine if one set of constraints is as strong as another set. This mismatch results in the C# compiler accepting some constructs that the runtime rejects and the result is the TypeLoadException you see. We are investigating to determine if this code is a manifestation of that problem. Regardless, it is certainly not "By Design" that the compiler accepts code like this that results in a runtime exception.
Regards,
Ed Maurer C# Compiler Development Lead
从我加粗的部分来看,我认为他是在说这是一个编译器错误。那是在 2007 年。我想这还不够严重,不足以成为他们修复它的优先事项。
关于c# - 为什么这种泛型场景会导致 TypeLoadException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6012420/
我尝试实现 azure 函数,但不断收到以下异常。 "TypeLoadException: Could not load type 'System.UriTemplate' from assemb
通过这个代码 module ObjectRe = type BM = A | N type Object = { Name: string Pattern: BM array
我正在编写一个 .NET 命令行应用程序,它将用户从现有数据库迁移到 aspnetdb。为了简化特定于用户的设置,我使用了 Joel Spolsky 撰写的关于 here 的配置文件类. 它在 ASP
我正在使用 Compact Framework 3.5/VS2008。我的 TypeLoadException 行为非常奇怪。以下代码抛出此错误。原因是数据库连接有问题。但是由于某些未知原因,此内部异
在我正在开发的一个简单应用程序中,我有三个相关的程序集: “MyCompany.Geography.Windows.Forms”,这是一个类库,其中包含 winforms 控件 “MyCompany.
所以我尝试将依赖项加载到我的代码中,然后我得到: TypeLoadException: Could not load type 'System.Data.SqlClient.SqlConnection
以下代码在 VS2013 和 VS2015 中编译,适用于从 2.0 到 4.6.1 的各种 .NET Framework 版本,但在执行时抛出 System.TypeLoadException: n
11 月 7 日 10:29 MST 更新 奇怪的是,如果我将属性从 ComponentModel 文件夹中移回 Common 项目的根目录,代码就可以正常工作。在为 InflowHealth.Com
这有点啰嗦,所以这里是快速版本: 为什么这会导致运行时 TypeLoadException?(编译器应该阻止我这样做吗?) interface I { void Foo(); } class
我正在编写一个 .NET 3.5 应用程序 (WinForms),它使用外部 DLL 中的类,并且每次应用程序尝试启动时我都会收到 System.TypeLoadException。 这是 VS 显示
一些背景知识:我最近从源代码 (https://github.com/ServiceStack/ServiceStack) 重新编译了 ServiceStack 库。在完成一些错误修复后,我还重新编译
当我尝试启动我的单元测试时,出现一个错误窗口: System.TypeLoadException: Method 'get_SolutionDirectory' in type 'JetBrains.
我在 Windows 应用商店应用程序中使用 Winmd(Windows 运行时组件)。当我尝试实例化在 winmd 中定义的类型时,出现以下异常: System.TypeLoadException
你能告诉我解决 System.TypeLoadException 问题的方法吗? 我的解决方案中的现有项目存在此异常,我从同一解决方案中的单元测试项目中引用了该项目。 当我运行我的单元测试时抛出这个异
我正在尝试使用以下代码将我的 Web API 连接到 MySql 数据库: public class Startup { public void ConfigureServices
我目前正在为我的公司管理一个 ASP.NET 应用程序。最近,当我尝试调试代码时遇到了 System.TypeLoadException。 确切的信息是: Inheritance security r
我在使用强类型集线器时遇到 TypeLoadException。我的界面是: public interface IClientCallback { void callback(T msg, s
我正在使用 VS2008 使用 C# 开发一个适用于 Honeywell Dolphin 6100 的应用程序,这是一款带有条码扫描器的移动数据终端,使用类似操作系统的 Windows CE 5.0。
你能否创建一个 .NET 4 版本的应用程序进行测试是老板们无辜的问题——当然! 但是在我将 Winforms 应用程序中的 27 个项目更改为 .NET 4 并重新编译后,在启动应用程序时,我得到了
在我们的 Azure 云服务中,我们使用 Mvc、WebApi 和 Autofac。 Mvc 和 WebApi 需要 System.Web.Http 版本5.2.3 Autofac.WebApi2想要
我是一名优秀的程序员,十分优秀!