[英]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()
我努力了:
public interface TSchool: IHasStudents, IHasTeachers, IHasAdmin, new()
但是编译器不喜欢new()
语法
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.