有人可以向我解释为什么会出现此错误
Someone can explain me why this error occurs I tried to create a provider to rosolver a list of service to make a connection from obj1 with service1
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
public abstract class Provider
{
public abstract string Name { get; }
}
public abstract class Provider<T> : Provider
where T : BaseService
{
public T Service { get; set; }
}
public class FooProvider : Provider<FooService>
{
public override string Name => "FooProvider";
}
public class BarProvider : Provider<BarService>
{
public override string Name => "BarProvider";
}
public abstract class BaseService
{
public abstract string Name { get; }
}
public class FooService : BaseService
{
public override string Name => "FooService";
}
public class BarService : BaseService
{
public override string Name => "BarService";
}
class Program
{
public static List<BaseService> Services = new List<BaseService> { };
public static List<Provider<BaseService>> Providers = new List<Provider<BaseService>> { };
static void Main()
{
Console.WriteLine("Services");
Services.Add(new FooService());
Services.Add(new BarService());
Services.ForEach(service => Console.WriteLine(service.Name));
Console.WriteLine("Provider");
// Error CS1503 Argument 1: cannot convert from 'ConsoleApp1.FooProvider' to 'ConsoleApp1.Provider<ConsoleApp1.BaseService>' ConsoleApp1 C:\Projetos\Git\sbh\src\ms\sbh - src - ms - migracao\ConsoleApp1\Program.cs 56 Active
Providers.Add(new FooProvider());
//Error CS1503 Argument 1: cannot convert from 'ConsoleApp1.BarProvider' to 'ConsoleApp1.Provider<ConsoleApp1.BaseService>' ConsoleApp1 C:\Projetos\Git\sbh\src\ms\sbh - src - ms - migracao\ConsoleApp1\Program.cs 61 Active
Providers.Add(new BarProvider());
Providers.ForEach(provider => Console.WriteLine($"provider {provider.Name} - service {provider.Service.Name}"));
}
}
}
如果您评论添加提供商的命令,您会发现错误不会发生。
我不知道为什么会发生错误,因为我知道简单的服务列表和供应商列表不工作。
这是因为泛型的协变性。您的示例中的服务之所以有效,是因为 List<T>
(或更准确地说 IEnumerable<T>
)被标记为具有协变参数类型。
这允许将 FooService 用作 BaseService。您的 Provider class 中的泛型未标有差异,因此不能以相同的方式使用。如果你想要这个功能,你需要创建一个变体通用接口。
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
public abstract class Provider
{
public abstract string Name { get; }
}
public abstract class Provider<T> : Provider
where T : BaseService
{
public T Service { get; set; }
}
public class FooProvider : Provider<FooService>
{
public override string Name => "FooProvider";
}
public class BarProvider : Provider<BarService>
{
public override string Name => "BarProvider";
}
public abstract class BaseService
{
public abstract string Name { get; }
}
public class FooService : BaseService
{
public override string Name => "FooService";
}
public class BarService : BaseService
{
public override string Name => "BarService";
}
class Program
{
public static List<BaseService> Services = new List<BaseService> { };
public static List<Provider<BaseService>> Providers = new List<Provider<BaseService>> { };
static void Main()
{
Console.WriteLine("Services");
Services.Add(new FooService());
Services.Add(new BarService());
Services.ForEach(service => Console.WriteLine(service.Name));
Console.WriteLine("Provider");
// Error CS1503 Argument 1: cannot convert from 'ConsoleApp1.FooProvider' to 'ConsoleApp1.Provider<ConsoleApp1.BaseService>' ConsoleApp1 C:\Projetos\Git\sbh\src\ms\sbh - src - ms - migracao\ConsoleApp1\Program.cs 56 Active
Providers.Add(new FooProvider());
//Error CS1503 Argument 1: cannot convert from 'ConsoleApp1.BarProvider' to 'ConsoleApp1.Provider<ConsoleApp1.BaseService>' ConsoleApp1 C:\Projetos\Git\sbh\src\ms\sbh - src - ms - migracao\ConsoleApp1\Program.cs 61 Active
Providers.Add(new BarProvider());
Providers.ForEach(provider => Console.WriteLine($"provider {provider.Name} - service {provider.Service.Name}"));
}
}
}
如果您评论添加提供商的命令,您会发现错误不会发生。 我不知道为什么会发生错误,因为我知道简单的服务列表和供应商列表不工作。
这是因为泛型的协变性。您的示例中的服务之所以有效,是因为 List<T>
(或更准确地说 IEnumerable<T>
)被标记为具有协变参数类型。
这允许将 FooService 用作 BaseService。您的 Provider class 中的泛型未标有差异,因此不能以相同的方式使用。如果你想要这个功能,你需要创建一个变体通用接口。