【问题标题】:C# Error 4 Cannot implicitly convert type. Generic Interfaces [closed]C# 错误 4 无法隐式转换类型。通用接口[关闭]
【发布时间】:2014-06-12 13:26:43
【问题描述】:

对于任何有 C# 经验的人来说,这个问题应该很容易解决。我想这样做,以便科目可以有一个课程列表。此应用程序中有导师和学生。因此,我创建了一个通用主题,它定义了 Tutor_Subject 和 Student_Subject 实现的属性。但是我遇到了一个奇怪的铸造错误。

public interface Subject<TCourse> where TCourse : Course
{
  int SubjectId { get; set; }
  string Name { get; set; }

  ICollection<TCourse> Courses { get; set; }
}

public partial class Student_Subject :Subject<Student_Course>
{
}

public partial class Tutor_Subject :Subject <Tutor_Course>
{
}

public interface Course
{
    int CourseId { get; set; }
    string Name { get; set; }
}

public partial class Student_Course :Course
{
}

public partial class Tutor_Course :Course
{
}

问题来了

无法将类型“Tutor_Subject”隐式转换为“Course”。存在显式转换(您是否缺少演员表?)

Subject<Course> subject;

if(type ==1)
{
    subject = new Student_Subject();  // Error 
    courseList = subjectInfo["courses"].ToObject<IList<Student_Course>>();
}
else
{
    subject = new Tutor_Subject();  // Error
    courseList = subjectInfo["courses"].ToObject<IList<Tutor_Course>>();
}

subject.Name = subjectName;
subject.Courses = courseList.ToList();

【问题讨论】:

  • 嗯,有什么问题吗? Student_SubjectSubject&lt;Student_Course&gt;不是 Subject&lt;Course&gt;subject 被声明为。
  • 我回答了这个问题,但我更喜欢删除它,因为您的问题不清楚,或者它错误的命名约定会造成很多混乱(接口以I 大写字母开头...),我相信存在设计缺陷。
  • 我怎样才能拥有一个由 Student_Subject 和 Tutor_Subject 实现的具有“课程”列表的主题接口。 Course是Student_Course和Tutor_Course实现的接口

标签: c# generics inheritance types casting


【解决方案1】:

从 C# 4 开始,当使用泛型时,您必须在泛型参数定义中使用 out 关键字明确告诉编译器泛型类型可能是更派生的类型(协变):

http://msdn.microsoft.com/en-us/library/dd469487.aspx

public interface Subject<out TCourse> where TCourse : Course
{
   int SubjectId { get; set; }
   string Name { get; set; }
   IEnumerable<TCourse> Courses { get; set; }
}

【讨论】:

  • 我现在明白 .Net 是如何非常类型安全的并且需要指定方差。我现在有最后一个问题。我收到“错误 1 ​​无效方差:类型参数 'TCourse' 必须在 '.ICourses' 上始终有效。'TCourse' 是协变的”。我尝试将 ICollection ICourses 更改为 ICollection ICourses 但我没有运气。
  • 将您的 ICollection 替换为 IEnumerable
  • 我这样做了,现在它说“无效的方差:类型参数 'TCourse' 必须在 '.ICourses' 上逆变有效。'TCourse' 是协变的”。这是我到目前为止的公共接口 ISubject where TCourse : ICourse {.... IEnumerable ICourses { get;放; }.....} .......比我有......公共接口ICourse
  • 你不能有一个getter和setter,因为你的集合不能同时是协变和逆变的(出和入)。
  • 阅读 Eric Lippert 关于方差有效性的帖子:blogs.msdn.com/b/ericlippert/archive/2009/12/03/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
  • 1970-01-01
  • 2022-01-06
  • 2015-08-04
  • 2012-12-01
  • 2014-02-12
  • 2014-04-18
相关资源
最近更新 更多