在 C# 中将 List<DerivedClass> 传递给期望 List<ParentClass> 的方法

Pass List<DerivedClass> to method expecting List<ParentClass> in C#

我正在创建一个应用程序,其中 returns 列出了在各种条件下使用的金属。我有一个金属 class 然后 class 是每种类型的金属,如钢、铝等。如果我有不同钢的列表,我想首先 select 最好的在所有金属共有的一组属性上,然后根据钢的独特属性进行第二遍。 (这不是我的确切问题,但我的问题是类似的。)

我不知道如何将 List 传递给 Metal class 的 GetBest() 方法,如下所示,该方法采用 List 类型的第一个参数。由于下面用 ** 突出显示的行中的错误,代码将无法编译:“参数 1:无法从 'System.Collections.Generic.List<Steel>' 转换为 'System.Collections.Generic.List<Metal>'。

public class Metal {

    public int PropA { get; set; }

    public List<Metal> GetBest( List<Metal> list, int condition1 )
    {
        var best = new List<Metal>();

      //Analysis code here...

        return best;
    }
}

public class Steel : Metal
{
    public int PropB { get; set; }

    public List<Steel> GetBest(List<Steel> list, int condition1, int condition2 ) {

        var bestSteel = new List<Steel>();

      //Do first pass selection based on properties of all metals.
        **bestSteel = Metal.GetBest(list, condition1);**

      //Do some additional analysis based to Steel's unique properties.
      //Analysis code here...

        return bestSteel;

    }

您可以使用受约束的泛型方法:

public static List<T> GetBest<T>(List<T> list, int condition1) where T : Metal
{
    var best = new List<T>();

    // Analysis code here...

    return best;
}

我要回答另一个问题!看看我如何解决这个问题,而不会将我的对象 (MetalSteel) 与我根据某些条件选择最佳金属的逻辑混淆:

public class Metal{}
public class Steel:Metal{}

public class MetalPickerContext
{
    public int Condition1{ get;set;}
}

public class MetalPicker<TMetal, TContext> 
    where TMetal: Metal
    where TContext: MetalPickerContext
{
    public virtual IEnumerable<TMetal> GetBest(IEnumerable<TMetal> list, TContext context)
    {
        var result = new List<TMetal>();
        // logic for picking the best metal based on Condition1
        
        return result;
    }
}

public class SteelPickerContext: MetalPickerContext
{
    public int Condition2{get;set;}
}

public class SteelPicker : MetalPicker<Steel,SteelPickerContext>
{
    public override IEnumerable<Steel> GetBest(IEnumerable<Steel> list, SteelPickerContext context)
    {
        var initialResult = base.GetBest(list,context);
        // Having called the base logic apply more with reference to Condition2
        return initialResult;
    }
}

这可以编译(如您所见 here),我可以稍微扩展示例,提供更多细节,使其成为一个有效的示例。让我知道这是否对您有帮助。