C# 添加类型参数约束以防止抽象类
如果抽象类的具体实现没有默认构造函数,是否可以将类型参数限制为这些实现 例如,如果我有:C# 添加类型参数约束以防止抽象类,c#,C#,如果抽象类的具体实现没有默认构造函数,是否可以将类型参数限制为这些实现 例如,如果我有: public abstract class Animal { private Animal() { } public Animal(string name) { // ... } // ... } public class Penguin : Animal { // ... } public class Chimpanz
public abstract class Animal
{
private Animal()
{
}
public Animal(string name)
{
// ...
}
// ...
}
public class Penguin : Animal
{
// ...
}
public class Chimpanzee : Animal
{
// ...
}
我还有以下课程:
public class ZooPen<T>
where T : Animal
{
// ...
}
公共类ZooPen
T:动物
{
// ...
}
我想允许新建ZooPen()
和新建ZooPen()
,但不允许新建ZooPen()
这是可能的吗?您可以添加
new()
约束,这将要求类不是抽象的,并且有一个默认构造函数。这里有一种方法可以实现您的要求
abstract class Animal
{
readonly string Name;
Animal() { }
public Animal(string name) { Name = name; }
}
abstract class Animal<T> : Animal where T : Animal<T>
{
public Animal(string name) : base(name) { }
}
class Penguin : Animal<Penguin>
{
public Penguin() : base("Penguin") { }
}
class Chimpanzee : Animal<Chimpanzee>
{
public Chimpanzee() : base("Chimpanzee") { }
}
class ZooPen<T> where T : Animal<T>
{
}
class Example
{
void Usage()
{
var penguins = new ZooPen<Penguin>();
var chimps = new ZooPen<Chimpanzee>();
//this line will not compile
//var animals = new ZooPen<Animal>();
}
}
抽象类动物
{
只读字符串名称;
动物(){}
公共动物(字符串名称){name=name;}
}
抽象类动物:动物,其中T:动物
{
公共动物(字符串名称):基(名称){}
}
企鹅类:动物
{
公共企鹅():基(“企鹅”){}
}
黑猩猩类:动物
{
公共黑猩猩():基(“黑猩猩”){}
}
类ZooPen,其中T:动物
{
}
课例
{
无效用法()
{
var penguins=new ZooPen();
var chimps=新的ZooPen();
//这一行不会编译
//var动物=新的ZooPen();
}
}
任何维护此代码的人都可能会有点困惑,但它正是您想要的
public class ZooPen<T> where T : Animal
{
public ZooPen()
{
if (typeof(T).IsAbstract)
throw new ArgumentException(typeof(T).Name + " must be non abstract class");
}
}
{
公共动物园()
{
if(类型为(T).IsAbstract)
抛出新ArgumentException(typeof(T).Name+“必须是非抽象类”);
}
}
谢谢,但我面临的问题是,具体类没有默认构造函数。@安德鲁:那么CLR类型系统就帮不了你了。对不起。@SLaks这正是我害怕的。谢谢。你为什么需要这个限制?是使用反射得到的构造函数创建子类吗?如果是这样的话,为什么不添加一个运行时检查来明确为什么会有限制,而不是一个潜在的令人困惑的编译时错误呢?我同意millimoose的观点。这个限制对我来说很难闻。如果您需要在Zoo笔中创建新实例,那么可以将工厂作为构造函数参数。@StriplingWarrior,我开始同意。millimoose是正确的,带有type参数的类通过反射实例化子类。无论如何,我正在重新考虑如何处理这个问题,所以谢谢你的建议。你也可以使用一个界面。(
其中T:Animal,ITypedAnimal
)