C#接口与通用类型相互引用

时间:2018-05-09 22:29:36

标签: c# inheritance interface multiple-inheritance

目前我正在处理很多类和这些类的列表。以前我静态方法,这些方法将获取特定的类列表并返回列表的子集或单个项。

但是我认为让类继承List并在那里拥有必要的方法并且不再使它们变为静态更方便,因此它们适用于您正在使用的任何对象列表。

我一直无法找到将List转换为继承此类的类的简单方法,因此我在所有这些集合类中创建了一个方法来为我转换它。

实施例

public class Student 
{
    public int Id {get;set;}
    public string Name {get;set;}
}
public class Students : List<Student>
{
    public Student GetTopStudent()
    {
        return this.OrderByDescending(s => s.Grade).FirstOrDefault();
    }

    public Students GetPassingStudents()
    {
        return this.Where(s => s.Grade > 0.7).ToCollection();
    }

    public Students ToCollection(IEnumerable<Student> studentsList)
    {
        var students = new Students();
        foreach(var s in studentsList)
        {
            students.Add(s);
        }
        return students();
    ]
}

我有很多其他类和类的列表,但这是一个非常简单的例子。我找到了一些方法,比如&#34; ToCollection()&#34;方法在类之间几乎相同,但返回类型和列表中包含的类型除外。

所以我尝试创建扩展和接口自动处理这些方法。

集合类和接口

public abstract class Collection<T> : List<T>
{
    // Needed tie in the extension method with the List.Add() Method
    public void Add(object item) => base.Add((T)item);
}

public interface IObjectWithId<T> 
    where T : IObjectWithId<T>
{
    int Id {get;set;}
}

public ICollectionItem<C> 
    where C : Collection<IcollectionItem<C>>
{
}

public ICollectionItemWithId<C,T> 
    where C : Collection<ICollectionItemWithId<C,T>>
    where T : IObjectWithId<T>
{
}

扩展

public static List<T> Get<T>(this IEnumerable<IobjectWithId<T>> list, List<int> ids)
    where T : IObjectWithId<T>
{
    return list.Where(i => ids.Contains(i.Id))
        .Cast<T>();
        .ToList();
}

public static C Get<C, T>(this IEnumerable<IcollectionItemWithId<C, T>> list, List<int> ids)
    where C : Collection<ICollectionItemWithId<C, T>>, new()
    where T : IObjectWithId<T>
{
    return list.Where(i => ids.Contains(i.Id)).ToCollection();
}

public static C ToCollection<C, T>(this IEnumerable<ICollectionItemWithId<C, T>> list)
    where C : Collection<ICollectionItemWithId<C, T>>, new()
    where T : IObjectWithId<T>
{
    var collection = new C();
    foreach(var item in list)
    {
        collection.Add(item);
    }
    return collection;
}

public static C ToCollection<C>(this IEnumerable<ICollectionItem<C>> list)
where C : Collection<ICollectionItem<C>>, new()
{
    var collection = new C();
    foreach(var item in list)
    {
        collection.Add(item);
    }
    return collection;
}

我一直无法使用此代码。通常我在构建它之后会出现错误,要么没有从学生类到学生列表的隐式引用转换,要么是有关拳击的错误。

我担心我的接口互相引用可能会产生很多问题,但我这样做的原因是我不必指定方法的返回类型,尽管可能会这样做这是最简单的事情......

1 个答案:

答案 0 :(得分:0)

你太复杂了。根本问题是你好奇的自我引用public interface IObjectWithId<T>。由于您不在界面本身的任何位置使用T,因此不需要通用。

只需编写适用于IEnumerable<T>的扩展方法,并通过对T的一些简单约束返回IEnumerable<T>,例如

// This does not need to be generic in any way
public interface IObjectWithId
{
    int Id {get;set;}
}

public static IEnumerable<T> Get<T>(this IEnumerable<T> list, List<int> ids)
    where T : IObjectWithId
{
    return list.Where(i => ids.Contains(i.Id));
}

如果他们愿意,请将来电链.ToList()置于此处。有时他们可能只想要一个(Single()First()),或者他们可能会在其后执行另一个过滤器或组操作,因此将其强制回List<T>效率很低。