我有以下代码:
public interface IEnrollment
{
bool IsGood { get; set; }
}
public interface IEnrollmentToRegion
{
int RegionId { get; set; }
}
public class ByRegion : IEnrollmentToRegion
{
public int RegionId { get; set; }
}
public class Enrollment : IEnrollment
{
public bool IsGood { get; set; }
public ICollection<ByRegion> Regions { get; set; }
}
public class Main
{
public void DoSomething()
{
var e = new Enrollment();
if (isEnrolled(e, c => c.Any(l => l.RegionId == 10)))
{
}
}
private bool isEnrolled<T>(Enrollment enrollment, Func<ICollection<T>, bool> test) where T : IEnrollmentToRegion
{
return true;
}
}
我要做的是创建方法isEnrolled,它接受IEnrollment类型的对象,在这个方法中我会做一堆检查,看看它是否返回true。我要检查的一件事是一组对象(在上面的例子中,它被简化为只有一个单独的类ByRegion类,但在我的实际中有多个Enrollment类,每个类都有它自己的独立集合,是不同类型的,但所有类型都有一个名为RegionId的属性。
所以我想传入一个函数来检查这些不同的集合,看看RegionId是否在集合中。我遇到的问题是我收到错误
c.Any(l => l.RegionId == 10))
说它不知道RegionId是什么。事实上,当我击中。在l
之后我没有得到任何智能感知。我不知道为什么我没有得到任何下拉列表,因为对T应该是IEnrollmentToRegion类型的限制,并且该类型上有RegionId。
答案 0 :(得分:2)
您的问题是,ByRegion
为IEnrollmentToRegion
时,ICollection<ByRegion>
不是ICollection<IEnrollmentToRegion>
。您可以使用反射测试:
//Returns true
return typeof(IEnrollmentToRegion).IsAssignableFrom(typeof(ByRegion));
//Returns false
return typeof(ICollection<IEnrollmentToRegion>).IsAssignableFrom(typeof(ICollection<ByRegion>));
因此,您无法指定T
并让类型推断为您处理。实际上,即使您明确指定了类型,例如:
isEnrolled<IEnrollmentToRegion>(e, c => c.Any(l => l.RegionId == 10))
您发现,一旦您尝试撰写isEnrolled<T>
的实际内容,您就会遇到问题。
以下是您的代码的更新版本:
public interface IEnrollment<T> where T:IEnrollmentToRegion
{
bool IsGood { get; set; }
ICollection<T> Regions { get; set; }
}
public interface IEnrollmentToRegion
{
int RegionId { get; set; }
}
public class ByRegion : IEnrollmentToRegion
{
public int RegionId { get; set; }
}
public class Enrollment : IEnrollment<ByRegion>
{
public bool IsGood { get; set; }
public ICollection<ByRegion> Regions { get; set; }
}
public class Main
{
public void DoSomething()
{
var e = new Enrollment();
e.Regions = new List<ByRegion>() { new ByRegion { RegionId = 10 } };
if (isEnrolled(e, c => c.Any(l => l.RegionId == 10)))
{
//This line gets hit
}
}
private bool isEnrolled<T>(IEnrollment<T> enrollment, Func<ICollection<T>, bool> test) where T : IEnrollmentToRegion
{
return test(enrollment.Regions);
}