Closed. This question needs details or clarity。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗?添加详细信息并通过editing this post阐明问题。
                        
                        5年前关闭。
                                                                                            
                
        
我有以下代码:

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的限制是T应该为IEnrollmentToRegion类型,并且该类型上具有RegionId。

最佳答案

您的问题是,虽然ByRegionIEnrollmentToRegion,但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);
        }

08-06 19:46