协变(List泛型作为方法参数时的父类子类问题)
共 5363字,需浏览 11分钟
·
2024-05-30 08:00
有段时间没搞.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<Person>
// 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;
[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();
}