手机网站建设方案书,网站不用下载免费软件,枞阳做网站的,3d建模是干什么的本章的主题是可变性#xff08;variance#xff09;#xff0c;这里的可变性更多的是指基类和派生类之间的转换。可变性分为三种#xff1a;协变#xff08;covariance#xff09;、逆变#xff08;contravariance#xff09;和不变#xff08;invariance#xff09;…本章的主题是可变性variance这里的可变性更多的是指基类和派生类之间的转换。可变性分为三种协变covariance、逆变contravariance和不变invariance。 文章目录 1. 协变1.1 协变的概念1.2 语法1.3 使用场景1.4 代码例子使用委托实现协变1.5 代码例子LINQ 中使用协变 2. 逆变2.1 逆变的概念2.2 语法2.3 使用场景2.4 代码示例委托中使用逆变2.5 代码示例事件处理中使用逆变 3. 一些问题3.1 协变和多态的区别概念区别主要区别总结 1. 协变
在C#中协变Covariance是一种允许将派生类类型替换为基类类型的特性。这种特性通常用于泛型类型或委托中特别是在返回类型时。协变的主要目的是提高代码的灵活性和可重用性使得在使用派生类时能够有效地利用基类的接口或方法。
1.1 协变的概念
协变是指在泛型类型的使用中允许将某个类型参数替换为该参数的派生类。换句话说协变允许你在泛型委托或接口中使用更具体的类型。在C#中协变通常用于返回值的情况。
1.2 语法
在C#中可以通过使用out关键字来声明协变类型参数。下面是协变的基本语法
public delegate TResult MyDelegateout TResult();这里TResult 参数前面加了out关键字表明这个类型参数是协变的。返回类型可以是派生类。
1.3 使用场景
协变的常见使用场景包括
委托在使用委托时协变允许将一个返回派生类的委托赋值给返回基类的委托。LINQ在LINQ查询中使用协变来处理不同类型的集合。事件处理在事件处理程序中使用协变来处理不同类型的事件。
1.4 代码例子使用委托实现协变
using System;// 基类
public class Animal
{public virtual void Speak(){Console.WriteLine(Animal speaks);}
}// 派生类
public class Dog : Animal
{public override void Speak(){Console.WriteLine(Dog barks);}
}// 定义一个协变的委托
public delegate T AnimalDelegateout T();class Program
{static void Main(){// 将返回Dog类型的委托赋值给返回Animal类型的委托AnimalDelegateAnimal animalDelegate GetDog;// 调用委托并输出结果Animal animal animalDelegate();animal.Speak(); // 输出: Dog barks}static Dog GetDog(){return new Dog();}
}输出
Dog barks1.5 代码例子LINQ 中使用协变
using System;
using System.Collections.Generic;
using System.Linq;public class Animal
{public string Name { get; set; }
}public class Dog : Animal { }class Program
{static void Main(){ListDog dogs new ListDog{new Dog { Name Buddy },new Dog { Name Max }};// 使用LINQ进行查询并返回基类类型的集合IEnumerableAnimal animals dogs.Select(d d);foreach (var animal in animals){Console.WriteLine(animal.Name); // 输出: Buddy, Max}}
}使用协变时应该注意以下几点
只能在返回值中使用协变而不能在方法参数中使用。协变使得代码更加灵活但也可能引入类型安全问题因此在使用时应谨慎。
2. 逆变
在C#中逆变Contravariance是与协变相反的特性允许将基类类型替换为派生类类型。逆变主要用于参数类型的上下文特别是在方法参数时。通过逆变我们可以使用更通用的类型来替代特定的类型从而提高代码的灵活性和可重用性。
2.1 逆变的概念
逆变是指在泛型类型的使用中允许将某个类型参数替换为该参数的基类。这种特性通常在需要处理不同类型的对象时非常有用。表现在代码上就是某个函数的参数类型是基类类型但是可以接受其派生类类型的实参。
2.2 语法
在C#中可以通过使用 in 关键字来声明逆变类型参数。下面是逆变的基本语法
public delegate void MyDelegatein T();2.3 使用场景
逆变的常见使用场景包括
委托在使用委托时逆变允许将一个接受派生类的委托赋值给接受基类的委托。事件处理在事件处理程序中使用逆变来处理不同类型的事件。集合操作在处理集合时逆变可以帮助简化参数类型的定义。
2.4 代码示例委托中使用逆变
下面的程序实现了一个基类类型的委托指向参数类型为基类类型的方法但是在执行委托时传入给委托的参数类型为派生类类型。
using System;// 基类
public class Animal
{public string Name { get; set; }
}// 派生类
public class Dog : Animal { }// 定义一个逆变的委托
public delegate void AnimalActionin T(T animal);class Program
{static void Main(){// 将接受Animal类型的委托赋值给接受Dog类型的委托AnimalActionAnimal animalAction MakeSound;Dog dog new Dog { Name Buddy };animalAction(dog); // 输出: Buddy makes a sound}static void MakeSound(Animal animal){Console.WriteLine(${animal.Name} makes a sound);}
}2.5 代码示例事件处理中使用逆变
下面的代码中实现了使用事件和逆变统一处理不同用户的目的。 public void AddUser(User user)
输出
John has been added.
Admin has been added.使用 in 和 out 关键字只适用于委托和接口不适用于类、结构和方法。
不包括 in 和 out 关键字的委托和接口类型参数叫做不变。这些类型参数不能用于协变和逆变。
3. 一些问题
3.1 协变和多态的区别
概念区别
多态多态是指子类可以替代父类的实例调用相同的方法但可能会有不同的实现。在面向对象编程中常通过继承和接口来实现多态性。
public class Animal
{public virtual void Speak(){Console.WriteLine(Animal speaks);}
}public class Dog : Animal
{public override void Speak(){Console.WriteLine(Woof!);}
}Animal myDog new Dog();
myDog.Speak(); // 输出: Woof!协变协变是指在泛型类型参数中允许用派生类替代基类。在 C# 中协变通常与泛型委托和接口相关允许使用更具体的类型作为返回值。
public delegate T CovariantDelegateout T();public class Animal { }
public class Dog : Animal { }public static Dog GetDog() new Dog();CovariantDelegateAnimal animalDelegate GetDog;
Animal animal animalDelegate(); // 使用协变主要区别总结
概念范围
多态是一个更广泛的概念涵盖了通过接口和继承实现不同类型之间的行为相同。协变是关于泛型类型参数的特定实现主要用于返回值的场景。
实现方式
多态通常通过方法重写override和接口实现来实现允许子类定义父类方法的具体实现。协变是通过在泛型定义中使用 out 关键字来实现允许使用更具体的类型作为返回值。
适用场景
多态主要用于运行时行为的动态选择允许对象通过父类接口调用不同的实现。协变主要用于数据结构和类型安全的情况下特别是在返回类型的灵活性方面。
各位道友码字不易记得一键三连呐。