簡體   English   中英

如何在 class 聲明之外聲明泛型類型

[英]How to declare a generic type outside of class declaration

我在整個測試應用程序中都成功使用了這個泛型類型聲明

public class TestController<TSchool>
    where TSchool: IHasStudents, IHasTeachers, IHasAdmin, new()

因為我將創建多個控制器,例如TestController<University>TestController<PrimarySchool> ,這些都很好用。

但是,在我需要使用TSchool的每個新 class 中重新鍵入<TSchool> where TSchool: IHasStudents, IHasTeachers, IHasAdmin, new()

我努力了:

  1. public interface TSchool: IHasStudents, IHasTeachers, IHasAdmin, new()

但是編譯器不喜歡new()語法

  1. public abstract class TSchool: IHasStudents, IHasTeachers, IHasAdmin, new()

也無濟於事。

有沒有辦法可以在每個 class 聲明之外聲明泛型類型?

泛型類型既不是接口也不是抽象 class,它是一個占位符,除了給定的名稱之外沒有任何意義。 這就是為什么您需要告訴 C# 該占位符究竟實現了什么才能使用其功能,至少是那些通過接口和/或諸如new()之類的特殊事物公開的功能。

您還有很多其他選擇,例如 inheritance。 而不是接受泛型類型,而是需要一個基類型。 object始終可用(盡管如果您將 go 提升到該級別,那么懶惰確實贏得了您的項目)。 dynamic也是一種選擇。 等等。

盡管我確實想知道為什么您需要能夠實例化這么多類型,以至於這首先成為一個問題。 也許依賴注入首先是您整個問題的答案。

您可以做的一件事是使用嵌套類

public class TestController<TSchool> where TSchool: IHasStudents, IHasTeachers, IHasAdmin, new()
{
    //don't need to re-declare TSchool, since TSchool is accessable in the nested classes
    public class TestA
    {

    }

    public class TestB
    {

    }
}

有了這個,您將不得不考慮一種初始化嵌套類的方法,這里有一些想法。

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //initialize controller
            var testController = new TestController<University>();

            //initialize Tests and pass the reference of the controller
            var testA_1 = new TestController<University>.TestA(testController);
            var testB_1 = new TestController<University>.TestB(testController);

            //initialize the Tests without a reference of the controller
            var testA_2 = new TestController<University>.TestA();
            var testB_2 = new TestController<University>.TestB();

            //use create methods, and maybe additionally hide the public constructors
            var testA_3 = testController.CreateTestA();
            var testB_3 = testController.CreateTestB();

            //use a static TestController class, and call the public constructors
            var testA_4 = new StaticTestController<University>.TestA();
            var testB_4 = new StaticTestController<University>.TestB();

            //use a static TestController class but hide the public constructors and use create methods 
            var testA_5 = StaticTestController<University>.CreateTestA();
            var testB_5 = StaticTestController<University>.CreateTestB();
        }
    }
}

public class TestController<TSchool> where TSchool : IHasStudents, IHasTeachers, IHasAdmin, new()
{
    private TSchool _school;

    public TestController()
    {
        _school = new TSchool();
    }
    public class TestA
    {
        public TestA()
        {

        }
        public TestA(TestController<TSchool> controller)
        {
            var school = new TSchool();
            var schoolController = controller._school;
        }
    }
    public class TestB
    {
        public TestB()
        {

        }
        public TestB(TestController<TSchool> controller)
        {
            var school = new TSchool();
            var schoolController = controller._school;
        }
    }
    public TestA CreateTestA()
    {
        return new TestA(this);
    }
    public TestB CreateTestB()
    {
        return new TestB(this);
    }
}
public static class StaticTestController<TSchool> where TSchool : IHasStudents, IHasTeachers, IHasAdmin, new()
{
    private static TSchool _school;

    static StaticTestController()
    {
        _school = new TSchool();
    }

    public class TestA
    {
        public TestA()
        {
            var school = new TSchool();
            var schoolController = _school;
        }
    }

    public class TestB
    {
        public TestB()
        {
            var school = new TSchool();
            var schoolController = _school;
        }
    }

    public static TestA CreateTestA()
    {
        return new TestA();
    }
    public static TestB CreateTestB()
    {
        return new TestB();
    }
}
public class School : IHasAdmin, IHasTeachers, IHasStudents
{

}
public class University : IHasAdmin, IHasTeachers, IHasStudents
{

}
public interface IHasStudents
{

}
public interface IHasTeachers
{

}
public interface IHasAdmin
{

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM