首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >我能满足一个具有兼容返回类型的接口吗?

我能满足一个具有兼容返回类型的接口吗?
EN

Stack Overflow用户
提问于 2018-01-25 03:40:04
回答 3查看 155关注 0票数 3

我有下面的片段

代码语言:javascript
运行
AI代码解释
复制
using System.Collections.Generic;

public interface IInventoryItem {}
public class      InventoryItem : IInventoryItem {}

public interface IInventory
{
    IEnumerable<IInventoryItem> Items { get; }
}

public class Inventory : IInventory
{
    public  IEnumerable<InventoryItem>  Items            => items;
    //      IEnumerable<IInventoryItem> IInventory.Items => items;

    private InventoryItem[] items = new InventoryItem[0];
}

我得到以下错误消息:

错误CS0738:Inventory不实现接口成员IInventory.Items.get,最佳实现候选Inventory.Items.get返回类型System.Collections.Generic.IEnumerable<InventoryItem>与接口成员返回类型System.Collections.Generic.IEnumerable<IInventoryItem>不匹配

添加IInventory.Items.get的显式实现确实是正确的,但是为什么它是必要的呢?

问题是:如果IEnumerable<InventoryItem>IEnumerable<IInventoryItem>,为什么InventoryItem[]不是InventoryItem[]

编辑:

关于为什么这很有趣:我的假设:

  • Items.get将始终返回一个有效的IEnumerable<IInventoryItem>
EN

回答 3

Stack Overflow用户

发布于 2018-01-25 03:44:23

这是必要的,因为IInventoryItem,而不是(也不能)仅限于由InventoryItem实现。

如果您(或其他任何人)将编写另一个实现IInventoryItem接口的类,那么实现IInventory接口的任何类都将能够处理这个问题,因为它只处理IInventoryItem接口,不知道或不关心具体的实现。

如果编译器允许像在您的问题中那样编写Inventory类,那么它将无法处理实现IInventoryItem接口的任何其他类。

为求澄清:

Items属性返回一个IEnumerable<InventoryItem>

如果添加了实现IInventoryItem的不同类,且该类没有从InventoryItem继承,则属性将无法返回该类的IEnumerable

假设您添加了这个类:

代码语言:javascript
运行
AI代码解释
复制
public class MyNotRelatedInventoryItem : IInventoryItem
{ /* implementation here */ }

您当前的Items属性将永远无法保存IEnumerable of MyNotRelatedInventoryItem,因为它与InventoryItem类没有任何关联。

票数 4
EN

Stack Overflow用户

发布于 2018-01-25 03:56:10

我补充了Zohar已经提到的内容,下面是如何通过泛型实现您想要的:

代码语言:javascript
运行
AI代码解释
复制
public interface IInventoryItem {}
public class      InventoryItem : IInventoryItem {}
public interface IInventory<T> where T : IInventoryItem
{
    IEnumerable<T> Items { get; } 
}

public class Inventory : IInventory<InventoryItem>
{
    public  IEnumerable<InventoryItem>  Items            => items;    
    private InventoryItem[] items = new InventoryItem[0];
}

但是,这有一个缺点,就是整个接口IInventory都是通用的,因为属性不能是泛型的。为了避免这种情况,您可以创建一个GetItems-method instea,它可以是通用的。

当您有一个接口时,您必须使用与该接口定义的完全相同的签名来实现它。出于同样的原因,你不能做以下事情:

代码语言:javascript
运行
AI代码解释
复制
interface MyInterface
{
    A A { get; }
}
class A : MyInterface
{
    public B A { get; private set; } // this will NOT implement the interface, although B derives from A
}
class B : A { }
票数 3
EN

Stack Overflow用户

发布于 2018-01-25 03:59:21

属性返回类型与接口类型不匹配,因此编译器不将其视为接口实现。所以你需要把它改为

代码语言:javascript
运行
AI代码解释
复制
public  IEnumerable<IInventoryItem> Items => items;

而不是

代码语言:javascript
运行
AI代码解释
复制
public  IEnumerable<InventoryItem> Items => items;

因为它存在从InvetoryItemIInventoryItem的隐式转换,所以编译器是可以的。

这是可能的,因为您只返回值,而且编译器知道数组中的每个InvetoryItem都可以转换为IInventoryItem类型,而不会引发异常。

如果您的界面如下所示:

代码语言:javascript
运行
AI代码解释
复制
public interface IInventory
{
    IEnumerable<IInventoryItem> Items { get; set; }
}

这是不可能的,下面的代码

代码语言:javascript
运行
AI代码解释
复制
public IEnumerable<IInventoryItem> Items
{
    get { return items; }
    set { items = value; }
}

将引发下列编译错误:

错误CS0266不能隐式地将“System.Collections.Generic.IEnumerable”类型转换为“ConsoleApplication1.InventoryItem[]”。显式转换存在(您缺少强制转换吗?)

这意味着编译器不能隐式地将任何IInventoryItem转换为InventoryItem,因为它无法确保该转换始终成功。

您必须像这样显式地转换:

代码语言:javascript
运行
AI代码解释
复制
public IEnumerable<IInventoryItem> Items
{
    get { return items; }
    set { items = (InventoryItem[])value; }
}

但是,如果数组不是完全由InvetoryItem对象组成,则可能出现异常。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48441990

复制
相关文章
Android实现Splash闪屏动画效果
这种效果的原理就是利用nineold提供的动画帮助类,做一个放大效果,子线程或者hanlder发消息延时两秒,然后对图片再执行放大效果,动画结束后跳转到首页
SoullessCoder
2020/11/23
2K0
ionic2 (真正)修改应用图标和启动画面
今天在用ionic2 的ionic resources生成新的icon和splash,生成后安装,应用图标和启动画面依然没变化。。。 不知道大家有没有被坑过,今天被坑了一下午,终于找到了办法: 解决方法 第一次使用ionic resources后根文件夹下会生成一个res文件夹,比如你的项目文件夹名是demo,那么就是demo/res文件夹。 将res中的所有文件夹复制到demo\platforms\android\res下,res里面的同名文件夹覆盖(注意:保留该文件夹下原本的values文件夹和xml文
mcq
2018/06/20
6720
cordova打包项目启动页面和图标的设置
在cordova5.0版本以后,需要安装cordova-plugin-splashscreen插件以后才能修改和设置App的启动页面。
安德玛
2022/03/09
1.3K0
cordova android
Image.png Image.png http://www.jscss.cc/2016/10/18/cordova.html 装一个全局的cordova: 官网介绍: http://cordova.apache.org/ Image.png 运行的时候自动弹出浏览器: Image.png Image.png Svon(555486L7I7L5对话) 11:20:29 webpack Svon(555486L7I7L5对话) 11:24:30 npm uninstall -g cordova
王小婷
2018/06/04
7030
Android 闪屏 Splash
android的实现非常简单,使用Handler对象的postDelayed方法就可以实现。在这个方法里传递一个Runnable对象和一个延迟的时间。该方法实现了一个延迟执行的效果,延迟的时间由第2个参数指定,单位是毫秒。第一个参数是Runnable对象,里面包含了延迟后需要执行的操作。 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceStat
iOSDevLog
2018/05/17
1.1K0
Ionic3学习笔记(一)安装、项目结构与常用命令
创建一个新项目,有blank、tabs、sidemenu3种样式可选,tutorial、super、conference为官方Demo,aws为AWS Mobile Hub Demo
Theo Tsao
2018/09/07
1.3K0
Hybrid App移动应用开发初探
  Native App(原生App)是用原生语言(Object-C/Java/C#/....)开发,用户需要下载安装的手机应用。
Edison Zhou
2018/08/21
3.6K0
Hybrid App移动应用开发初探
cordova-android版本
这样会添加默认版本号的,如android@6.2.3,如果安装某些cordova插件时对cordova-android版本有要求,如:
IT晴天
2018/08/20
3950
cordova-android版本
capacitor 设置开屏图片和图标
安装库 npm install -g cordova-res 建立文件夹 在项目目录下建立resources resources/ ├── icon.png └── splash.png 创建资源文件 cordova-res ios --skip-config --copy cordova-res android --skip-config --copy 复制到Android文件夹中
Laikee
2022/04/25
9380
cordova-cli@8.0和cordova-android@7.0.0问题说明
默认安装cordova-android@~7.0.0,实际上大于等于7.0的当前可选版本就只有cordova-android@7.0.0,所以安装了它。
IT晴天
2018/08/20
9940
cordova-cli@8.0和cordova-android@7.0.0问题说明
Cordova 初识
Cordova 是使用 HTML,CSS 和 JavaScript构建混合移动应用程序的平台。官方文档给了我们 Cordova 的定义。
acc8226
2022/05/17
1.3K0
Cordova 初识
cordova run android 下载gradle报timeout
1)下载zip包 https://services.gradle.org/distributions/gradle-4.1-all.zip
治电小白菜
2020/08/25
9500
cordova run android 下载gradle报timeout
Android应用icon和闪屏splash的尺寸
我查看支付宝钱包的时候,发现drawable-xxxhdpi里面的尺寸是180 x 180,不是上面标的192 x 192
meteoric
2018/11/19
2K0
cordova编译android app之苦逼心路
遇到的问题: FAILURE: Build failed with an exception. * What went wrong: Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'. > Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager. * Try:
周星星9527
2021/11/15
1.3K0
cordova编译android app之苦逼心路
手把手教你搭建android模块化项目框架(十)——美好的项目从Splash开始
原因是android app在启动时,由于application初始化等原因会有一个短暂的延迟,导致点击launcher后不能马上启动activity并渲染。通常我们使用的方案是添加SplashActivity,并且将windowbackground设置成app品牌图标等方式能够让用户点击launcher后快速相应并展示,提升用户体验。
支离破碎_superLee
2023/09/01
3820
android系统开机画面_Android开机画面
Android Splash Screen is the first screen visible to the user when the application’s launched. Splash screen is one of the most vital screens in the application since it’s the user’s first experience with the application.
全栈程序员站长
2022/08/27
9840
Android 必知必会-Android Splash 页秒开之细节处理
今天阅读了两篇 Android Splash 页秒开的文章,就上手试了试,效果确实不错,不过在使用过程中发现个小的问题,应用是发现在 Android 6.0 系统下 APP 启动的时候有个默认的动画,如果按照文章介绍的直接启动下一个加载数据的页面会出现页面闪动,有点美中不足的感觉。
他叫自己MR.张
2019/07/01
1.1K0
Android 12上全新的应用启动画面,还不适配一下?
我们常常花费精力去打造引导画面或广告画面,而作为第一印象的启动画面却容易被忽视。回想下以前都是怎么处理这个画面的:
Rouse
2021/05/28
3.1K0
Android 12上全新的应用启动画面,还不适配一下?
【Android】常用技巧汇总(持续更新)
新建Activity,命名为Splash 跳转时间设为2000ms Splash.java
zstar
2022/06/14
3590
点击加载更多

相似问题

查找小数点后的有效位数和小数位数。

40

BigDecimal允许使用的有效位数是多少

11

如何用小数点两位来格式化数字?

12

如何格式化6位或9位数字,如#、##、###

20

Java获得双小数位数的前2位

46
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档