协变(List泛型作为方法参数时的父类子类问题)

有段时间没搞.net的项目了(没办法,谁让国内JAVA流行是事实)。最近又回归.net(哪里需要哪里搬~)。

接收到需求后,一顿输出,结果…咦?编译失败???
在这里插入图片描述
错误信息:

CS1503:参数1:无法从"System.Collections.Generic.List<Student>" 转换为"Person"

额…仔细回想下(好久不搞.net,.net的理论知识都已经落灰了)。

下面是完整的测试代码:


public class Person
{public string Name { get; set; }public int Age { get; set; }
}
public class Student :Person
{public string School { get; set; }public decimal Score { get; set; }
}
public abstract class Point
{ public Person person { get; set; }public List<Person> persons { get; set; }/// <summary>/// 单个/// </summary>public abstract void Info();/// <summary>/// 批量/// </summary>public abstract void List();
}public class PointStudent : Point
{public PointStudent(Person data){this.person = data;}public PointStudent(List<Person> data){this.persons = data;}public override void Info(){Console.WriteLine($"{((Student)person).Name}就读于{((Student)person).School}");}public override void List(){this.persons.ForEach(p => { this.person = p; Info(); });}
}static void Main(string[] args)
{Student student = new Student() { Name="张三",Age = 18,School ="东师"};Point point = new PointStudent(student);point.Info();List<Student> students = new List<Student>() { student };Point pointList = new PointStudent(students);pointList.List();
}

那么问题来了…

为什么使用子类的对象作为参数传入时没有错误?

答:

  • 后期绑定(Polymorphism):C# 支持后期绑定,这意味着在运行时确定方法的实际执行版本,而不是在编译时确定。

  • 继承和多态性:子类继承了基类的所有特性,同时可以拥有自己的特性和行为。当你将子类对象传递给期望基类类型的方法时,方法将根据子类对象的实际类型执行相应的操作。

为什么使用List时报错?

答:

  • 对于List和List,这是List类型,可以理解为2个不相干的类,不存在继承关系,所以不能直接作为参数传入。

怎么解决?

答:

  • 这里就用到了协变, 协变允许将一个派生类对象赋值给一个基类对象。

协变示例:


// Covariance.
IEnumerable<string> strings = new List<string>();  
// An object that is instantiated with a more derived type argument
// is assigned to an object instantiated with a less derived type argument.
// Assignment compatibility is preserved.
IEnumerable<object> objects = strings;

从C#4.0开始,IEnumerable 的声明中引入了 out 关键字,它表示这个接口支持协变性。


[TypeDependency("System.SZArrayHelper")]
[__DynamicallyInvokable]
public interface IEnumerable<out T> : IEnumerable
{[__DynamicallyInvokable]new IEnumerator<T> GetEnumerator();
}

那么上面这段代码该怎么修改?


public class Person
{public string Name { get; set; }public int Age { get; set; }
}public class Student :Person
{public string School { get; set; }public decimal Score { get; set; }
}public abstract class Point
{ public Person person { get; set; }public IEnumerable<Person> persons { get; set; }/// <summary>/// 单个/// </summary>public abstract void Info();/// <summary>/// 批量/// </summary>public abstract void List();
}public class PointStudent : Point
{public PointStudent(Person data){this.person = data;}public PointStudent(IEnumerable<Person> data){this.persons = data;}public override void Info(){Console.WriteLine($"{((Student)person).Name}就读于{((Student)person).School}");}public override void List(){this.persons.ForEach(p => { this.person = p; Info(); });}
}static void Main(string[] args)
{Student student = new Student() { Name="张三",Age = 18,School ="东师"};Point point = new PointStudent(student);point.Info();List<Student> students = new List<Student>() { student };Point pointList = new PointStudent(students);pointList.List();
}

其实代码改动比较简单,大多数的程序员都知道该怎么去调整,这里我就多啰嗦了,需要注意的是:在岗位上拧螺丝的时候,不要忘了去回顾下自己的知识栈,保持技术的鲜活~


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/842132.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 常用命令大全!!

Docker 常用命令 一、启动类1. 启动 docker2. 关闭 docker3. 重新启动 docker4. docker 设置自启动5. 查看 docker 运行状态6. 查看 docker 版本号等信息7. docker 帮助 二、 镜像类1. 查看镜像2. 搜索镜像3. 拉取镜像4. 运行镜像5. 删除镜像6. 加载镜像7. 保存镜像 三、容器类…

react解决电脑分辨率及缩放导致页面变形的问题

此处借鉴Vue3 解决电脑分辨率及缩放导致页面变形的问题-CSDN博客&#xff1a; 新建devicePixelRatio.js&#xff1a; /*** description 校正windows页面在系统进行缩放后导致页面被放大的问题&#xff0c;通常放大比例是125%、150%* **/class DevicePixelRatio {constructor(…

python-opencv 边缘检测、直线检测、圆检测

文章目录 Canny算法霍夫变换-直线检测霍夫变换-圆形检测 Canny算法 除了将目标与背景分离开来&#xff0c;边缘检测也同样是一种图像分割方法&#xff0c;从分割结果来看&#xff0c;adaptiveThreshold函数显然就采取了类似边缘检测的划分方案。 Canny在1986年提出了一种边缘…

【源码】2024完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城

后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 前端UNIAPP 后端PHP 一键部署版本 获取方式&#xff1a; 微&#xff1a;uucodes

代码随想录算法训练营第四十一天|动态规划理论基础、509. 斐波那契数列、70. 爬楼梯、746. 使用最小花费爬楼梯

动态规划理论基础 什么是动态规划 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就…

X2Doris使用指南:界面化数据迁移工具 - 轻松实现整库迁移至Doris

什么是X2Doris X2Doris 是 SelectDB 团队开发的&#xff0c;专门用于将各种离线数据迁移到 Apache Doris 中的核心工具&#xff0c;该工具集 自动建 Doris 表 和 数据迁移 为一体&#xff0c;目前支持了 Apache Doris/Hive/Kudu/StarRocks 数据库往 Doris 或 SelectDB Cloud 迁…

Oracle AVDF(审计保险库和数据库防火墙)常见问题

此文是AVDF FAQ的翻译注解&#xff08;斜体&#xff09; 通用问题 审计库和数据库防火墙的最新版本是什么&#xff1f; Oracle Audit Vault 和 Database Firewall (AVDF) 的最新版本是版本更新 11 (AVDF 20.11)。请阅读公告博客和发行说明以了解更多详细信息。 Oracle Audit …

一屏万象,场景无限:蓝牙墨水屏标签多功能多场景应用带您领略未来

在数字化浪潮汹涌澎湃的今天&#xff0c;智能科技产品层出不穷&#xff0c;它们不仅极大地改变了我们的生活方式&#xff0c;更在无形中拓宽了我们的视野。而今&#xff0c;一款融合了创新技术与实用性于一体的蓝牙墨水屏标签&#xff0c;正以其多功能多场景应用的特性&#xf…

在GoDaddy网站托管上托管Next.js , npm项目步骤

要在GoDaddy网站托管上托管一个使用Next.js构建的npm项目&#xff0c;步骤&#xff1a; 1. 准备Next.js项目 确保Next.js项目已经准备好&#xff0c;并且可以在本地运行。可以使用以下命令来启动项目&#xff1a; npm install npm run build npm start2. 设置GoDaddy主机 登…

strstr的使⽤和模拟实现

strstr&#xff08;function&#xff09; Returnsa pointer to the irst occurrence of str2 in str1, or a null pointer if str2 is not part of str1. &#xff08;函数返回字符串str2在字符串str1中第⼀次出现的位置&#xff09;。 The matchingprocess doesnot include t…

无线麦克风什么品牌好?一文读懂无线领夹麦克风哪个品牌音质最好

​当我们谈论到演讲、表演或者录制视频时&#xff0c;一个高质量的无线麦克风能够使得整个体验提升至一个全新的水平。它不仅能够保证声音的清晰度和真实度&#xff0c;还能够让使用者在演讲或者表演时更加自信和舒适。基于对市场的深入研究和用户体验的考量&#xff0c;我挑选…

在微信公众号怎么添加留言板功能

在如今信息爆炸的时代&#xff0c;微信公众号已成为企业与用户互动的重要桥梁。如何在这个平台上脱颖而出&#xff0c;吸引用户的眼球&#xff0c;提升用户黏性&#xff0c;成为每一个公众号运营者都需要思考的问题。今天&#xff0c;我们就来聊聊如何在微信公众号中巧妙添加留…

车辆相关识别API优化您的车辆系统

车辆相关识别API是开发者们所需的重要工具&#xff0c;它们基于先进的计算机视觉和深度学习技术&#xff0c;提供了强大的车辆识别和分类能力。这些API能够从图像或视频中快速准确地识别和提取车辆的关键信息&#xff0c;如车辆型号、品牌、颜色等。对于开发者而言&#xff0c;…

1251. 平均售价

1251. 平均售价 题目链接&#xff1a;1251. 平均售价 代码如下&#xff1a; # Write your MySQL query statement below select p.product_id,round(ifnull(sum(units*price)/sum(units),0),2) as average_price from Prices as p left join UnitsSold as u on p.product_id…

机器学习:探索数据的魔法世界

课程链接&#xff1a;AI小天才&#xff1a;让你轻松掌握机器学习 引言&#xff1a; 在当今数字化的时代&#xff0c;数据无处不在&#xff0c;而机器学习则是解析、理解和利用这些数据的魔法钥匙。从自动驾驶到智能推荐系统&#xff0c;机器学习的应用无所不在&#xff0c;给我…

k8s问题

文章目录 本地搭K8s集群 bilibili什么是声明式API&#xff1f;kubectl apply Etcd数据库有什么特性&#xff0c;为什么K8S选用了Etcd数据库&#xff1f;K8S中一个node的生命周期是怎样的&#xff1f;服务发现机制介绍docker的实现原理介绍如果只是使用Linux命名空间进行分离&am…

【深度学习】最强算法之:人工神经网络(ANN)

人工神经网络ANN 1、引言2、人工神经网络(ANN)2.1 定义2.1.1 定义2.1.2 应用场景 2.2 核心原理2.3 实现方式2.4 算法公式2.5 代码示例 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;看新闻没&#xff1f; 小鱼&#xff1a;新闻天天看&#xff0c;啥事大惊小怪的。 小屌…

Python数据分析-心脏病(随机森林预测分析)

本次案例分析用心脏病数据集来做随机森林模型预测 导入基本的数据分析包 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score…

【Python】【报错解决】【无法安装socket库】No matching distribution found for socket

一、问题描述 如下图&#xff0c;笔者在做一个安全相关的项目时&#xff0c;遇到如下报错&#xff1a; No matching distribution found for socket 在尝试安装socket&#xff08;套接字&#xff09;库时报错&#xff0c;报错代码&#xff1a; pip install socket二、原因及解…

【信息论系列2】蜂窝通信得基本概念和信道容量等相关计算

基本概念 已经看到,为了确保完全的区域覆盖而没有死点,可以使用一系列正多边形。 出于经济原因,通常采用六边形(六边形的设计比正方形或三角形更有效)。基于简单几何,相邻六边形之间的中心到中心的距离 x x x由 3 R \sqrt{3}R