You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#跨类数组问题:驱动类接收自定义数组遇阻及输出异常排查

问题解决与代码优化方案

1. 控制台输出P1CPSC3200.Formula+TypesForArrays[]的原因及解决

直接调用Console.WriteLine(Formulas)时,C#默认调用数组的ToString()方法,该方法返回数组的类型全名而非实际内容。要正确输出数组数据,有两种方案:

方案1:给TypesForArrays重写ToString()方法

public class TypesForArrays
{
    public int numofOre = 2;
    public int numofStick = 1;
    public string Diam = "Diamonds";
    public string Gold = "Gold Ingots";
    public string Iron = "Iron Ingots";
    public string Stick = "Sticks";

    // 自定义输出格式
    public override string ToString()
    {
        return $"矿石数量: {numofOre}, 木棍数量: {numofStick}, 资源类型: {Diam}/{Gold}/{Iron}/{Stick}";
    }
}

客户端遍历输出:

foreach(var item in formula1.Formulas)
{
    Console.WriteLine(item);
}

方案2:客户端直接遍历输出属性

foreach(var item in formula1.Formulas)
{
    if(item != null) // 避免空引用异常
    {
        Console.WriteLine($"矿石: {item.numofOre}, 木棍: {item.numofStick}, 钻石: {item.Diam}");
    }
}

2. 实现支持多种数据类型的配方数组

当前TypesForArrays是固定结构,无法灵活适配多种资源类型,可通过抽象基类+派生类实现扩展性:

// 通用资源基类
public abstract class Resource
{
    public string Name { get; set; }
    public int Quantity { get; set; }
}

// 具体资源派生类
public class OreResource : Resource { }
public class StickResource : Resource { }

// Formula类中修改配方数组类型
public List<Resource>[] Formulas = new List<Resource>[1];

每个配方可自由组合资源,比如钻石剑配方:

Formulas[0] = new List<Resource> 
{ 
    new OreResource { Name = "Diamonds", Quantity = 2 }, 
    new StickResource { Name = "Sticks", Quantity = 1 } 
};

3. 减轻客户端负载的优化

  • 封装内部数据:将Formulas设为私有,提供公共方法暴露配方信息,避免客户端直接操作内部数组:
private List<Resource>[] _formulas = new List<Resource>[1];

// 获取指定配方的方法
public List<Resource> GetRecipe(int index)
{
    if(index >=0 && index < _formulas.Length)
        return _formulas[index];
    return null;
}

客户端仅需调用GetRecipe(0)获取配方,无需关心内部结构。

  • 提取公共逻辑:MakeDiamondSword和Apply逻辑高度重复,提取公共方法减少冗余:
// 计算制作结果的公共方法
private int CalculateCraftResult()
{
    const int DiamondSword = 10;
    int chance = Percentage();
    return chance switch
    {
        P75 => DiamondSword * P75,
        P110 => DiamondSword * P110,
        P100 => DiamondSword * P100,
        P0 => DiamondSword * P0,
        _ => -1
    };
}

// 制作方法(扣除资源)
public int MakeDiamondSword()
{
    if (Diamond > 1 && Stick > 0)
    {
        Diamond -= 2;
        Stick -= 1;
        Proficiency += 1;
        return CalculateCraftResult();
    }
    return -1;
}

// 模拟制作(不扣除资源)
public int Apply()
{
    if (Diamond > 1 && Stick > 0)
    {
        return CalculateCraftResult();
    }
    return -1;
}

4. 配方功能的完善建议

  • 分离配方数据与逻辑:将每种物品的配方(资源类型、数量)存入Formulas数组,制作时动态读取配方扣除资源,避免硬编码资源数值。
  • 初始化配方数组:当前Formulas是长度为1的空数组,需在构造函数中初始化元素,避免空引用异常:
public Formula(int Dia, int Sti)
{
    Diamond = Dia;
    Stick = Sti;
    // 初始化配方元素
    Formulas[0] = new TypesForArrays();
}

内容的提问来源于stack exchange,提问作者bchennnn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 01:04:59