Ale*_*tch 21 c# linq interface data-conversion implicit-conversion
我正在使用名为DDay ICal的类库.它是在Outlook日历中实现的iCalendar系统的C#包装器,以及许多更多系统.我的问题来源于我在使用这个系统时所做的一些工作.
这里有3个问题
IRecurrencePattern:并非显示所有代码
public interface IRecurrencePattern
{
string Data { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
RecurrencePattern:并非显示所有代码
public class RecurrencePattern : IRecurrencePattern
{
public string Data { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
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}" };
}
}
Run Code Online (Sandbox Code Playgroud)
令人困惑的部分:通过DDay.ICal系统,他们使用ILists来包含日历中每个事件的重复模式集合,自定义类用于从数据库中获取信息,然后通过它转换为重复模式.隐式类型转换运算符.
但在代码中,我发现它一直崩溃转换到时List<IRecurrencePattern>从List<DbRecurPatt>我意识到我需要转换为RecurrencePattern,然后转换为IRecurrencePattern(因为是实现其他类IRecurrencePattern不同,它们也包含在集合中
var unsorted = new List<DbRecurPatt>{ new DbRecurPatt(), new DbRecurPatt() };
var sorted = unsorted.Select(t => (IRecurrencePattern)t);
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用,它会引发错误IRecurrencePattern.
var sorted = unsorted.Select(t => (IRecurrencePattern)(RecurrencePattern)t);
Run Code Online (Sandbox Code Playgroud)
这确实有效,所以我的问题是; 为什么第一个不起作用?(有没有办法改进这种方法?)
我相信这可能是因为隐式运算符在RecurrencePattern对象而不是接口上,这是正确的吗?(我是接口和隐式运算符的新手)
ang*_*son 16
您基本上已经要求编译器执行此操作:
DbRecurPattIRecurrencePattern 尽管编译器可能只有一个选项,但编译器不允许您这样做.演员操作员明确表示DbRecurPatt可以转换为a RecurrencePattern,而不是a IRecurrencePattern.
编译器仅检查所涉及的两种类型中的一种是否指定了关于如何从一种转换为另一种的规则,它不允许中间步骤.
由于没有定义允许DbRecurPatt直接转换的运算符IRecurrencePattern,编译器会将其编译为硬转换,通过接口将引用重新解释为引用,这将在运行时失败.
所以,接下来的问题是:我怎么能这样做呢?答案是你不能.
编译器不允许您在接口上定义用户定义的转换运算符.Stack Overflow上的另一个问题有更多信息.
如果您尝试定义此类运算符:
public static implicit operator IRecurrencePattern(DbRecurPatt obj)
{
return new RecurrencePattern() { Data = $"{obj.Name} - {obj.Description}" };
}
Run Code Online (Sandbox Code Playgroud)
编译器会这样说:
CS0552'DbRecurPatt.implicit
operator IRecurrencePattern(DbRecurPatt)':不允许在接口之间进行用户定义的转换
为什么第一个不起作用?
因为您要求运行时进行两次隐式转换 - 一次转换为RecurrencePattern一次转换IRecurrencePattern.运行时只会查找直接的隐式关系 - 它不会扫描所有可能的路由以让您去询问它.假设对实现的不同类型的类有多个隐式转换IRecurrencePattern.运行时选择哪一个?相反,它会强制您指定单独的强制转换.
这在C#语言规范的第6.4.3节中有记录:
评估用户定义的转换从不涉及多个用户定义或提升的转换运算符.换句话说,从类型S到类型T的转换将永远不会首先执行从S到X的用户定义转换,然后执行从X到T的用户定义转换.
| 归档时间: |
|
| 查看次数: |
1104 次 |
| 最近记录: |