问题 1:
很简单的一个方法, 判断给点数字是不是在另两个数字范围内.
public static bool Between(int i, int[] range)
{
return i >= range[0] && i <= range[1];
}
但是现在不仅仅是要判断 int, 还可能是 long, float, double.
这种在 C#里应该怎么做? 下面这样的写法编译报错.
public static bool Between<T>(T i, T[] range) where T: int, long, float, double
{
return i >= range[0] && i <= range[1];
}
问题 2:
方法里用到个链表, 需要限制链表里必须是动物, 但是可能是猫也可能是狗. 这种应该怎么写?
下面这样的是无法通过编译的
List<Animal> list = new List<Cat>();
list = new new List<Dog>();
1
hez2010 2022-09-17 21:14:19 +08:00 1
针对数学的泛型是在 C# 11 才引入的,所以需要 .NET 7 ,目前发了 RC 版本。
第一个问题: 可以使用 `IComparisonOperators` 作为约束: ```csharp using System.Numerics; static bool Between<T>(T i, T[] range) where T : IComparisonOperators<T, T, bool> { return i >= range[0] && i <= range[1]; } ``` 第二个问题: 你直接用 `List<Animal> list = new List<Animal>()` 就行了,然后可以调用 `list.Add(new Dog())` 和 `list.Add(new Cat())` 往里面添加狗或者猫。 .NET 泛型可以向上或者向下转类型,这个分别叫做协变和逆变,只能在接口上用,例如: ```csharp void Test1(IFoo1<object> s) { IFoo1<string> x = s; // ok } void Test2(IFoo2<string> s) { IFoo2<object> x = s; // ok } interface IFoo1<in T> { } interface IFoo2<out T> { } ``` |
2
bthulu OP @hez2010 @hez2010 第二个问题, 我这里没这么简单.
实际是从配置文件中读取类似下面这样的 public class Config { public string Farmer {get;set;} public List<Dog> Dogs {get;set;} public List<Cat> Cats {get;set;} } 然后在另一个方法里动态引用 Dogs 或 Cats public void DoSomething(string animalType) { Config config = ReadFromJsonFile(); // 这个赋值会报错, 无法将 List<Dog>或 List<Cat>赋值给 List<Animal> List<Animal> animals = animalType switch { "Dog" => config.Dogs, "Cat" => config.Cats, _ => config.Cats } foreach(var animal in animals) { animal.Dance(); } } |
3
bthulu OP @hez2010 刚才又试了下, .net core 里是没有 IComparisonOperators 这个类的, 你这个怕不是.net framework4.x 里的吧
|
6
yor1g 2022-09-17 23:44:20 +08:00 1
这不是都用接口来约束不就行了 何必要具体类或基础类型来做约束... 都是面向对象基础
|
7
beyondex 2022-09-18 01:31:18 +08:00 via Android
1 楼正解
|
8
Magentaize 2022-09-18 08:36:45 +08:00 via iPhone
List 是 class 不实现协变,只有接口可以实现协变
|