3

次のようなインターフェースを作成したい...

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

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

ですから、具体的な実装は不可能であることをはっきりと知っていますが、マルチエンティティの再投稿を行い、スーパーベースのインターフェイスを作成する方法はありますか?

4

3 に答える 3

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()ご覧のとおり、アプリケーションがどのメソッドを呼び出すかを認識できるように、クラスを明示的にキャストする必要があります。

于 2012-07-30T16:29:15.420 に答える
0

これは私には欠陥のある設計アプローチのように聞こえますが、メソッドは戻り型によってのみ変更できず、言語はその方法で型パラメーターのリストをサポートしていないため、不可能です。

共通の基本クラスを実装して、それらを基本クラスのリスト(List<Person> personRepository;)に格納できます。次に、特定のタイプのメンバーをフェッチするのは、Linq拡張機能を使用すると簡単List<Students> = personRepository.OfType<Student>().ToList();です。

于 2012-07-30T16:50:47.673 に答える
-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
    }
    }

これは、従業員と学生が基本インターフェースを共有しているため、同じリポジトリに追加できることを意味します。後でそれらを抽出し、簡単にアクセスできるようにIEntityに共通のフィールド(名前、年齢など)を配置できます。

于 2012-07-30T16:19:39.423 に答える