이 글에서는 주로 C# 역산과 공분산 관련 정보를 자세하게 소개하고 있으니 참고할만한 가치가 있으니 관심 있는 분들은 참고하시기 바랍니다.
이 글에서는 델리게이터와 람다 식을 많이 사용합니다. 완전한 지식 시스템을 구축하는 데 도움이 되는 "위임 및 익명 위임" 및 "익명 위임 및 람다 표현식" 기사를 확인하세요.
C#의 탄생부터 발전과 성장까지의 과정에서 새로운 지식 포인트가 끊임없이 소개됩니다. 반공변성(Contravariance)과 공분산(Covariance)은 C#에 원래 있는 것이 아니며 나중에 소개될 것입니다. Java에도 반공변성(Contravariance)과 공변성(Covariance)이 존재합니다. 앞으로는 Java 반공변성(Contravariance)과 공분산(Covariance)에 대한 글을 쓸 예정입니다. 관심 있는 친구들은 주목해 보세요.
공분산과 공분산은 추상적이고 심오하게 들릴 수도 있지만 실제로는 매우 간단합니다. 아래 코드를 보세요:
class Person { } class Student : Person { } class Teacher: Person { } class Program { static void Main(string[] args) { List<Person> plist = new List<Person>(); plist = new List<Student>(); plist = new List<Teacher>(); } }
위 코드에서 plist = new List
C# 4.0 이전에는 위와 같은 할당 작업이 허용되지 않았습니다. 허용되지 않는 이유는 형식 안전성이 주요 요소입니다. 아래 샘플 코드를 살펴보세요.
List<Person> plist = new List<Student>(); plist.Add(new Person()); plist.Add(new Student()); plist.Add(new Teacher());
다음 예제에서는 List
하지만 C# 4.0 이후에는 상황이 달라졌습니다. "불가능한 일이 일어났다"가 아니라, 애플리케이션의 유연성이 새롭게 조정되었다는 것입니다. 마찬가지로 위 프로그램은 C# 4.0에서는 여전히 허용되지 않지만 예외가 발생합니다. C# 4.0부터 일반 대리자 및 일반 인터페이스에서 특별한 상황이 발생할 수 있습니다(본질적으로 나중에 설명할 특별한 변경 사항이 발생하지 않았습니다). 다음 예:
delegate void Work<T>(T item); class Person { public string Name { get; set; } } class Student : Person { public string Like { get; set; } } class Teacher : Person { public string Teach { get; set; } } class Program { static void Main(string[] args) { Work<Person> worker = (p) => { Console.WriteLine(p.Name); }; ; Work<Student> student_worker = (s) => { Console.WriteLine(s.Like); }; student_worker = worker; //此处编译错误 } }
이전 이론적 지원에 따르면, Student_worker = Worker; 오류는 이해하기 쉽습니다. 그러나 여기서 우리 프로그램의 목적은 작업자가 Work
1. Student_worker(s)를 호출할 때 실제로 실행되는 것은 waker(s)이므로 s 변수의 유형이 성공적이어야 합니다. waker 유형에 필요한 매개변수로 변환됩니다.
2. Work
조건 1 Student_worker()를 호출할 때 컴파일러는 매개 변수가 Person 유형 객체로 성공적으로 변환될 수 있는 Student 유형 객체여야 한다는 메시지를 표시합니다.
조건 2에서는 Woke 위임 정의를 다음과 같이 조정해야 합니다.
delegate void WorkIn<in T>(T item);
위임 이름을 WorkIn으로 변경하는 것은 수정 전과 후의 위임을 구별하기 위한 것입니다. in 키워드를 추가하여 일반 대리자의 형식 매개 변수 T를 표시하고 이를 대리자 메서드의 매개 변수로만 사용합니다. 이 시점에서 위 프로그램은 성공적으로 컴파일되고 실행될 수 있습니다.
delegate void WorkIn<in T>(T item); class Program { static void Main(string[] args) { WorkInwoker = (p) => { Console.WriteLine(p.Name); }; WorkIn student_worker = woker; student_worker(new Student() { Name="tom", Like="C#" }); } }
유형 매개변수는 하위 유형이어야 하고 할당 유형 매개변수는 상위 유형 값이 허용되는 상황을 반공변성이라고 합니다. C#의 반공변성에서는 제네릭의 형식 매개 변수를 표시해야 합니다. 반공변성을 반공변성이라고 부르지만 이는 형식적으로는 상위 클래스 객체가 하위 클래스 변수에 할당되는 것처럼 보입니다. 본질적으로 이는 메서드가 호출될 때 매개 변수의 유형 변환입니다. Student s = new Person(), 이는 불가능합니다. 이는 반공변이 아니며 오류입니다.
위 코드를 다음과 같은 형태로 변환할 수 있다면 반전은 잊어도 됩니다. 현상보다 본질이 더 중요합니다.
위 내용은 C#의 반공변성(Contravariance) 및 공분산(Covariance)에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!