是否可以向通用接口添加类型列表?

时间:2012-07-30 16:14:24

标签: c#

我想创建一个界面,如...

interface IRepository<params T>
{
    T GetAll();
}

class PersonRepository : IRepository<Employees,Students>
{
    Employees GetAll();
    Students GetAll();
}

很明显我知道具体的实现是不可能的,但有没有办法采取多实体转发并创建一些超级基础接口?

3 个答案:

答案 0 :(得分:6)

这是可能的:

namespace ConsoleApplication12
{
    public class Employee
    {
        public string EmpName { get; set; }

        public override string ToString()
        {
            return this.EmpName;
        }
    }

    public class Student
    {
        public string StudName { get; set; }

        public override string ToString()
        {
            return this.StudName;
        }
    }

    public class Other
    {
        public int TestField { get; set; }

        public override string ToString()
        {
            return this.TestField.ToString();
        }
    }

    public interface IRepository<T>
    {
        List<T> GetAll();
    }

    public class PersonRepository : IRepository<Employee>, IRepository<Student>, IRepository<Other>
    {
        List<Student> IRepository<Student>.GetAll()
        {
            return new List<Student> { new Student { StudName = "test2" } };
        }

        List<Other> IRepository<Other>.GetAll()
        {
            return new List<Other> { new Other { TestField = 42 } };
        }

        List<Employee> IRepository<Employee>.GetAll()
        {
            return new List<Employee> { new Employee { EmpName = "test1" } };
        }
    }

    public class Program
    {
        private static void Main(string[] args)
        {
            PersonRepository d = new PersonRepository();

            // Returns "test1"
            Console.WriteLine(((IRepository<Employee>)d).GetAll()[0]);

            // Returns "test2"
            Console.WriteLine(((IRepository<Student>)d).GetAll()[0]);

            // Returns 42
            Console.WriteLine(((IRepository<Other>)d).GetAll()[0]);

            Console.ReadLine();
        }
    }
}

如您所见,您必须明确地投射您的类,以便您的应用程序可以知道要调用的GetAll()方法。

答案 1 :(得分:0)

这对我来说听起来像一个有缺陷的设计方法,并且不可能,因为方法不能仅因返回类型而异,并且语言不支持这种方式的类型参数列表。

您可以实现公共基类并将它们存储在基类的列表(List<Person> personRepository;)中。然后使用Linq扩展名即List<Students> = personRepository.OfType<Student>().ToList();来获取给定类型的成员很简单。

答案 2 :(得分:-2)

一点也不,但你可以这样做:

// base interface for entity types
interface IEntity 
{
}

class Employees : IEntity
{
}

class Students : IEntity
{
}

interface IRepository<T1, T2> where T1:IEntity where T2:IEntity
{
    T1 GetAll();
    T2 GetAll();
}

class PersonRepository : IRepository<Employees,Students>
{
    Employees GetAll();
    Students GetAll();
}

不幸的是,动态不能改变类型参数的数量。

或者你可以这样做:

// base interface for entity types
interface IEntity 
{
}

class Employees : IEntity
{
}

class Students : IEntity
{
}

interface IRepository 
{
    RegisterEntities(IEnumerable<IEntity> entities);

    IEnumerable<IEntity> GetAll();
}

class PersonRepository : IRepository
{
    IEnumerable<IEntity> GetAll() 
    {
       // Todo
    }
    }

这意味着您可以将Employees和Students添加到同一个存储库,因为它们共享一个基本接口。稍后您可以提取它们并在IEntity上放置公共字段(例如Name,Age)以便于访问。