如何将 object1 转换为 object1 的接口的接口
本文关键字:接口 object2 object1 转换 | 更新日期: 2023-09-27 18:34:27
假设我有这样的安排:
public interface ICreatable
{
int CreatedByUserId { get; set; }
}
public class Unicorn : ICreatable
{
public int CreatedByUserId { get; set; }
}
public interface ICrudService<T>
where T : class, ICreatable
{
T DoSomething(T t);
}
public class UnicornService : ICrudService<Unicorn>
{
public Unicorn DoSomething(Unicorn unicorn)
{
var createdByUserId = unicorn.CreatedByUserId;
// ...
return unicorn;
}
}
并像这样使用它:
static void Main(string[] args)
{
var unicorn = new Unicorn();
var unicornService = new UnicornService();
unicornService.DoSomething(unicorn);
}
这运行良好。但是,假设我想将unicornService
转换为ICrudService
的接口类型以及它的通用类型,如下所示的接口类型:
var crudService = unicornService as ICrudService<ICreatable>;
我遇到了问题。这是它的外观:
unicornService as ICrudService<Unicorn> --> casts is fine
unicornService as ICrudService<ICreatable> --> casts to null
似乎既然Unicorn
源于ICreatable
,而且既然ICrudService<T> where T: class, ICreatable
,解决这个问题应该没有问题。我的搜索开始引导我进入协方差和逆变,但我在这个层面上迷失了方向。
如何将crudService
投射到ICrudService<ICreatable>
?
更新:
使用协方差如下:
public interface ICrudService<out T>
然后让智能感知说"无效方差:类型参数'T'在'ICrudService.DoSomething(T)'上必须逆变有效。T' 是协变的。这是如何工作的?
ICrudService<Unicorn>
不能被视为ICrudService<ICreatable>
。
ICrudService<Unicorn>
对象只允许接受Unicorn
类型的参数或Unicorn
的子类型,但ICrudService<ICreatable>
可以接受SomeOtherTypeOfICreatable
的参数。
你UnicornService
类型被允许使用特定于Unicorn
的成员,而不仅仅是ICreatable
,因为这是它限制其函数的类型。 该限制禁止它满足更通用接口的 API。
所以,简而言之,这是不可能的。
你应该将 DoSomething 更改为接受 ICreatable,而不是 T 以使用 T 修饰符:
public interface ICrudService<out T>
where T : class, ICreatable
{
T DoSomething(ICreatable t);
}
public class UnicornService : ICrudService<Unicorn>
{
public Unicorn DoSomething(ICreatable t)
{
var unicorn = (Unicorn)t;
var createdByUserId = unicorn.CreatedByUserId; // or t.CreatedByUserId
// ...
return unicorn;
}
}
请注意,如果非独角兽将被传递给独角兽服务,则此代码将引发异常。