简体   繁体   English

解决C#中泛型缺少“ new(parameters)”的问题

[英]Workaround the lack of 'new(parameters)' in generic in C#

I found two ways to workaround the lack of 'new(parameters)' in generics but I'm wondering if there's a better solution for that situation. 我找到了两种方法来解决泛型中缺少'new(parameters)'的问题,但是我想知道对于这种情况是否有更好的解决方案。

I require a method in Earth that creates any Fruit using the Dna as parameter in ctor. 我需要在Earth中使用Dna作为ctor中的参数创建任何Fruit的方法。 I have lots of fruits. 我有很多水果。

Using Activator (or any similar form) has the disadvantage that breaks if the derived class has not the corret ctor or are abstract. 使用Activator(或任何类似形式)的缺点是,如果派生类没有正确的或抽象的类,则它会中断。

public class Earth
{
    public Earth()
    {
        var dna = new Dna();
        var orange = GetFruit<Orange>(dna);
    }

    private static T GetFruit<T>(Dna dna) where T : Fruit
    {
        return (T)Activator.CreateInstance(typeof(T), dna);
    }
}

public abstract class Fruit
{
    public Fruit(Dna dna)
    {

    }
}

public class Orange : Fruit
{
    public Orange(Dna dna)
        : base(dna)
    {

    }
}

public class Dna
{

}

Using a parameterless ctor has the disadvantage that the mandatory Dna becomes optional. 使用无参数ctor的缺点是强制Dna变为可选。 The same for a 'Initialize(Dna dna)' method. “ Initialize(Dna dna)”方法也是如此。

public class Earth
{
    public Earth()
    {
        var dna = new Dna();
        var orange = GetFruit<Orange>(dna);
    }

    private static T GetFruit<T>(Dna dna) where T : Fruit, new()
    {
        return new T() { Dna = dna };
    }
}

public abstract class Fruit
{
    public Dna Dna { get; set; }
}

public class Orange : Fruit
{

}

public class Dna
{

}

One option is to add another parameter: a Func<Dna, T> : 一种选择是添加另一个参数: Func<Dna, T>

private static T GetFruit<T>(Dna dna, Func<Dna, T> ctor) where T : Fruit
{
    // I assume your real code does more here?
    return ctor(dna);
}

Then you can use: 然后,您可以使用:

var orange = GetFruit(dna, x => new Orange(x));

Note that that also means you don't need to specify the type argument explicitly. 请注意,这也意味着您不需要显式指定type参数。 The downside is that if you're going to call this from another generic method, you'd need to pass the construction delegate throughout the stack :( 缺点是,如果要从另一个通用方法调用此方法,则需要在整个堆栈中传递构造委托:(

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM