c# - 接口(interface)、继承、隐式运算符和类型转换,为什么会这样?

标签 c# linq interface implicit-conversion data-conversion

我正在使用名为 DDay ICal 的类库。 它是在 Outlook 日历中实现的 iCalendar 系统的 C# 包装器,以及更多的系统。 我的问题源 self 在使用该系统时所做的一些工作。

这里有3个对象

  • IRecurrencePattern - 接口(interface)
  • RecurrencePattern - IRecurrencePattern 接口(interface)的实现
  • DbRecurPatt - 具有隐式类型运算符的自定义类

IRecurrencePattern:未显示所有代码

public interface IRecurrencePattern
{
    string Data { get; set; }
}

RecurrencePattern:未显示所有代码

public class RecurrencePattern : IRecurrencePattern
{
    public string Data { get; set; }
}

DbRecurPatt:未显示所有代码

public class DbRecurPatt
{
    public string Name { get; set; }
    public string Description { get; set; }

    public static implicit operator RecurrencePattern(DbRecurPatt obj)
    {
        return new RecurrencePattern() { Data = $"{Name} - {Description}" };
    }
}

令人困惑的部分:在整个 DDay.ICal 系统中,他们使用的是 IList s 包含日历中每个事件的循环模式集合,自定义类用于从数据库中获取信息,然后通过隐式类型转换运算符将其转换为循环模式。

但在代码中,我注意到它在转换为 List<IRecurrencePattern> 时一直崩溃来自List<DbRecurPatt>我意识到我需要转换为 RecurrencePattern , 然后转换为 IRecurrencePattern (因为还有其他以不同方式实现 IRecurrencePattern 的类也包含在集合中

var unsorted = new List<DbRecurPatt>{ new DbRecurPatt(), new DbRecurPatt() };
var sorted = unsorted.Select(t => (IRecurrencePattern)t);

上面的代码不起作用,它在 IRecurrencePattern 上抛出错误.

var sorted = unsorted.Select(t => (IRecurrencePattern)(RecurrencePattern)t);

这确实有效,所以我的问题是;为什么第一个不起作用? (有没有办法改进这种方法?)

我相信这可能是因为隐式运算符在 RecurrencePattern 上对象而不是接口(interface),这是正确的吗? (我是接口(interface)和隐式运算符的新手)

最佳答案

你基本上要求编译器这样做:

  1. 我有这个:DbRecurPatt
  2. 我想要这个:IRecurrencePattern
  3. 请找出从第 1 点到第 2 点的方法。

编译器,即使它可能只有一个选择,也不允许您这样做。转换运算符特别说明 DbRecurPatt 可以转换为 RecurrencePattern,而不是 IRecurrencePattern

编译器只检查所涉及的两种类型中的一种是否指定了如何从一种类型转换为另一种类型的规则,它不允许中间步骤。

由于没有定义允许 DbRecurPatt 直接转换为 IRecurrencePattern 的运算符,因此编译器会将其编译为硬转换,将引用重新解释为引用一个接口(interface),它将在运行时失败。

所以,下一个问题是:我该怎么做?答案是你不能。

编译器不允许您定义用户定义的转换运算符到接口(interface)或从接口(interface)返回。 A different question here on Stack Overflow has more information .

如果您尝试定义这样的运算符:

public static implicit operator IRecurrencePattern(DbRecurPatt obj)
{
    return new RecurrencePattern() { Data = $"{obj.Name} - {obj.Description}" };
}

编译器会这样说:

CS0552
'DbRecurPatt.implicit operator IRecurrencePattern(DbRecurPatt)': user-defined conversions to or from an interface are not allowed

关于c# - 接口(interface)、继承、隐式运算符和类型转换,为什么会这样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32226871/

相关文章:

c++ - `undefined reference` 尝试连接 C 以调用 C++

c# - 更改 launchSettings.json 中的端口会导致到达 "This site can’”

c# - 将 json 转换为 c# 对象列表

vb.net - 调试后期绑定(bind)操作无法在 Visual Studio 中转换为表达式树

Linq - Orderby 不排序

entity-framework - Entity Framework 5.0 First 或 Group By Issue - 从 2.2 升级到 5.0 之后

c# - 在 C# 中使用存储过程

c# - 泛型是运行时多态还是编译时多态?

android - 在 Kotlin 中将接口(interface)作为参数传递

java - 编译失败