- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
首先,请记住一个 .NET String
两者都是 IConvertible
和 ICloneable
.
现在,考虑以下非常简单的代码:
//contravariance "in"
interface ICanEat<in T> where T : class
{
void Eat(T food);
}
class HungryWolf : ICanEat<ICloneable>, ICanEat<IConvertible>
{
public void Eat(IConvertible convertibleFood)
{
Console.WriteLine("This wolf ate your CONVERTIBLE object!");
}
public void Eat(ICloneable cloneableFood)
{
Console.WriteLine("This wolf ate your CLONEABLE object!");
}
}
ICanEat<string> wolf = new HungryWolf();
wolf.Eat("sheep");
class
中接口(interface)列表的顺序
HungryWolf
的声明. (尝试交换逗号 (
,
) 分隔列表中的两个接口(interface)。)
String
两者都是
Iconvertible
(接口(interface))和
ICloneable
(界面)。这两个接口(interface)都不是从另一个接口(interface)派生的。
StackOverflowException
都是
SystemException
(直接基类)和
Exception
(基类的基类)。然后(如果
ICanEat<>
和以前一样):
class Wolf2 : ICanEat<Exception>, ICanEat<SystemException> // also try reversing the interface order here
{
public void Eat(SystemException systemExceptionFood)
{
Console.WriteLine("This wolf ate your SYSTEM EXCEPTION object!");
}
public void Eat(Exception exceptionFood)
{
Console.WriteLine("This wolf ate your EXCEPTION object!");
}
}
static void Main()
{
var w2 = new Wolf2();
w2.Eat(new StackOverflowException()); // OK, one overload is more "specific" than the other
ICanEat<StackOverflowException> w2Soe = w2; // Contravariance
w2Soe.Eat(new StackOverflowException()); // Depends on interface order in Wolf2
}
class
中的接口(interface)列表顺序宣言。但我认为更糟的原因是这一次有人可能认为重载决议总是选择
SystemException
因为它比
Exception
更具体.
最佳答案
我相信编译器在带有警告的 VB.NET 中做得更好,但我仍然认为这还不够。不幸的是,“正确的事情”可能要么要求禁止某些可能有用的东西(使用两个协变或逆变的泛型类型参数实现相同的接口(interface)),要么向语言引入新的东西。
就目前而言,除了 HungryWolf
之外,编译器现在没有任何地方可以分配错误。类(class)。这就是一个类声称知道如何做一些可能不明确的事情的时候。它在说明
I know how to eat an
ICloneable
, or anything implementing or inheriting from it, in a certain way.And, I also know how to eat an
IConvertible
, or anything implementing or inheriting from it, in a certain way.
ICloneable
和一个 IConvertible
.如果给它一个
HungryWolf
的实例,这不会给编译器带来任何痛苦。 ,因为它可以肯定地说“嘿,我不知道在这里做什么!”。但是当它被赋予
ICanEat<string>
时,它会给编译器带来痛苦。实例。
编译器不知道变量中对象的实际类型是什么,只知道它确实实现了 ICanEat<string>
.
HungryWolf
存储在该变量中,它模棱两可地实现了两次完全相同的接口(interface)。所以当然,我们不能在尝试调用
ICanEat<string>.Eat(string)
时抛出错误。 ,因为该方法存在并且对于可以放入
ICanEat<string>
的许多其他对象完全有效。变量(
batwad 在他的一个回答中已经提到了这一点)。
HungryWolf
的分配反对
ICanEat<string>
变量是不明确的,它不能防止它分两步发生。一个
HungryWolf
可以分配给
ICanEat<IConvertible>
变量,可以传递给其他方法并最终分配给
ICanEat<string>
多变的。
这两个都是完全合法的赋值 编译器不可能提示任何一个。
HungryWolf
从实现两个类
ICanEat<IConvertible>
和
ICanEat<ICloneable>
当
ICanEat
的泛型类型参数是逆变的,因为这两个接口(interface)可以统一。然而,这个
删除了编写有用内容的能力 没有替代的解决方法。
HungryWolf
类来实现两个接口(interface),但它也需要实现接口(interface)
ICanEat<IConvertible & ICloneable>
接口(interface),其中泛型类型参数实现两个接口(interface)。这可能不是最好的语法(这个
Eat(T)
方法的签名是什么样的,
Eat(IConvertible & ICloneable food)
?)。可能,更好的解决方案是在实现类上自动生成泛型类型,以便类定义类似于:
class HungryWolf:
ICanEat<ICloneable>,
ICanEat<IConvertible>,
ICanEat<TGenerated_ICloneable_IConvertible>
where TGenerated_ICloneable_IConvertible: IConvertible, ICloneable {
// implementation
}
callvirt
的泛型类一样构造接口(interface)实现类型。操作说明:
.class auto ansi nested private beforefieldinit HungryWolf
extends
[mscorlib]System.Object
implements
class NamespaceOfApp.Program/ICanEat`1<class [mscorlib]System.ICloneable>,
class NamespaceOfApp.Program/ICanEat`1<class [mscorlib]System.IConvertible>,
class NamespaceOfApp.Program/ICanEat`1<class ([mscorlib]System.IConvertible, [mscorlib]System.ICloneable>)!TGenerated_ICloneable_IConvertible>
callvirt
通过为
HungryWolf
构造接口(interface)实现来说明与
string
作为
TGenerated_ICloneable_IConvertible
的泛型类型参数,并检查它是否比其他接口(interface)实现更好地匹配。
string
的情况下和
char[]
,最大的共同点是 {
object
,
ICloneable
,
IEnumerable<char>
} (
IEnumerable
被
IEnumerable<char>
覆盖)。
interface ICanReturn<out T> where T: class {
}
class ReturnStringsOrCharArrays:
ICanReturn<string>,
ICanReturn<char[]>,
ICanReturn<TGenerated_String_ArrayOfChar>
where TGenerated_String_ArrayOfChar: object|ICloneable|IEnumerable<char> {
}
TGenerated_String_ArrayOfChar
在这种情况下(一个或多个接口(interface)是通用的)总是必须被视为
object
,即使公共(public)基类已经派生自
object
;因为
公共(public)类型可以在不继承公共(public)基类的情况下实现公共(public)接口(interface) .
关于c# - 当逆变导致歧义时,没有警告或错误(或运行时失败),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13568337/
我已经使用 vue-cli 两个星期了,直到今天一切正常。我在本地建立这个项目。 https://drive.google.com/open?id=0BwGw1zyyKjW7S3RYWXRaX24tQ
您好,我正在尝试使用 python 库 pytesseract 从图像中提取文本。请找到代码: from PIL import Image from pytesseract import image_
我的错误 /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference
我已经训练了一个模型,我正在尝试使用 predict函数但它返回以下错误。 Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]])
根据Microsoft DataConnectors的信息我想通过 this ODBC driver 创建一个从 PowerBi 到 PostgreSQL 的连接器使用直接查询。我重用了 Micros
我已经为 SoundManagement 创建了一个包,其中有一个扩展 MediaPlayer 的类。我希望全局控制这个变量。这是我的代码: package soundmanagement; impo
我在Heroku上部署了一个应用程序。我正在使用免费服务。 我经常收到以下错误消息。 PG::Error: ERROR: out of memory 如果刷新浏览器,就可以了。但是随后,它又随机发生
我正在运行 LAMP 服务器,这个 .htaccess 给我一个 500 错误。其作用是过滤关键字并重定向到相应的域名。 Options +FollowSymLinks RewriteEngine
我有两个驱动器 A 和 B。使用 python 脚本,我在“A”驱动器中创建一些文件,并运行 powerscript,该脚本以 1 秒的间隔将驱动器 A 中的所有文件复制到驱动器 B。 我在 powe
下面的函数一直返回这个错误信息。我认为可能是 double_precision 字段类型导致了这种情况,我尝试使用 CAST,但要么不是这样,要么我没有做对...帮助? 这是错误: ERROR: i
这个问题已经有答案了: Syntax error due to using a reserved word as a table or column name in MySQL (1 个回答) 已关闭
我的数据库有这个小问题。 我创建了一个表“articoli”,其中包含商品的品牌、型号和价格。 每篇文章都由一个 id (ID_ARTICOLO)` 定义,它是一个自动递增字段。 好吧,现在当我尝试插
我是新来的。我目前正在 DeVry 在线学习中级 C++ 编程。我们正在使用 C++ Primer Plus 这本书,到目前为止我一直做得很好。我的老师最近向我们扔了一个曲线球。我目前的任务是这样的:
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我的网站中有一段代码有问题;此错误仅发生在 Internet Explorer 7 中。 我没有在这里发布我所有的 HTML/CSS 标记,而是发布了网站的一个版本 here . 如您所见,我在列中有
如果尝试在 USB 设备上构建 node.js 应用程序时在我的树莓派上使用 npm 时遇到一些问题。 package.json 看起来像这样: { "name" : "node-todo",
在 Python 中,您有 None单例,在某些情况下表现得很奇怪: >>> a = None >>> type(a) >>> isinstance(a,None) Traceback (most
这是我的 build.gradle (Module:app) 文件: apply plugin: 'com.android.application' android { compileSdkV
我是 android 的新手,我的项目刚才编译和运行正常,但在我尝试实现抽屉导航后,它给了我这个错误 FAILURE: Build failed with an exception. What wen
谁能解释一下?我想我正在做一些非常愚蠢的事情,并且急切地等待着启蒙。 我得到这个输出: phpversion() == 7.2.25-1+0~20191128.32+debian8~1.gbp108
我是一名优秀的程序员,十分优秀!