Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 添加类型参数约束以防止抽象类_C# - Fatal编程技术网

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