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

本文关键字:参数 问题 泛型 解决 new | 更新日期: 2023-09-27 18:35:15

我找到了两种解决泛型中缺少"new(参数)"的方法,但我想知道是否有更好的解决方案来解决这种情况。

我需要地球上的方法,使用 ctor 中的 DNA 作为参数创建任何水果。我有很多水果。

使用 Activator(或任何类似形式)的缺点是,如果派生类没有相应的 ctor 或抽象,则会中断。

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
{
}

使用无参数 ctor 的缺点是强制 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
{
}

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

一种选择是添加另一个参数: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);
}

然后,您可以使用:

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

请注意,这也意味着不需要显式指定类型参数。缺点是,如果要从另一个泛型方法调用它,则需要在整个堆栈中传递构造委托:(