【问题标题】:C# ClassA has many ClassB, how to access ClassA instance method from ClassB instance [closed]C# ClassA 有很多 Class B,如何从 Class 实例访问 Class 实例方法 [关闭]
【发布时间】:2016-07-20 16:58:32
【问题描述】:

我的 C# 程序需要接收 xml 数据并将其存储在 sql 数据库中。我有很多说明的批次。我因此实现了这些类:

class Batch
{
    public string batchUID { get; set; }
    public Instruction[] instructionArray { get; set; }
}

class Instruction
{
    public string instructionUID { get; set; }
}

我的程序是这样运行的

Batch myBatch = new Batch();
myBatch.instructionArray = new Instruction[3];
myBatch.instructionArray[0] = new Instruction();
SomeFunc(myBatch.instructionArray[0]);

public void SomeFunc(Instruction instruction)
{
    // How do I do the following?
    console.write( instruction.OWNER.batchUID )
}

我尝试过广泛搜索,但每个结果都与继承、内部/外部类等有关。如果可能,我想避免在类指令中创建 batchUID 方法。

【问题讨论】:

  • new Instruction[3] 只是调整数组大小,所有值都是null,其中没有Instruction 实例。您必须创建它们,而最好的时机是将父级作为参数传递给Instruction 的构造函数。
  • 你必须以某种方式设置你的指令。 myBatch.instructionArray[2] = new Instruction { instructionUid = "foo" };
  • 我是否实例化 myBatch.instructionArray[n] 对我的问题没有影响...
  • @p4ndepravity 但是您提供的代码示例有一个严重的错误,只会导致NullReferenceException。所以我必须在你遇到麻烦之前指出这一点。

标签: c# .net class parent-child has-many


【解决方案1】:

您可以将Batch 的实例传递给Instruction 的构造函数,然后存储对该Batch 的引用,您可以使用属性公开该引用。 (这已经在另一个答案中显示 - 我重复它,因为它为我接下来要添加的内容提供了上下文。)

class Instruction
{
    public Instruction(Batch parent)
    {
        Parent = parent;
    }

    public Batch Parent { get; private set; }
    public string InstructionUID { get; set; } 
}

现在Instruction 有一个Parent 属性,它返回一个Batch

但是有一个差距。如果你打电话

var parent = batch.Instruction[0].Parent

parent == batch?看来这就是本意。 Instruction 包含对包含它的 Batch 的引用。

但没有什么强制执行。例如,我可以这样做:

someBatch.Instruction[0] = someOtherBatch.Instruction[1];

现在someBatch 包含一个Instruction 数组,但其中至少有一个实际上将someOtherBatch 作为其父级。

也许这种可能性没什么大不了,但我认为如果Parent 是指包含InstructionBatch 但它可能不是,那么你实际上并没有实现你的目标为了。

我建议创建一个包含BatchInstruction 的单独类。 (也许是ParentInstructionRelation?)

public class ParentInstructionRelation
{
    Batch Parent {get;private set;}
    Instruction Instruction {get;private set;}

    public ParentInstructionRelation(Batch parent, Instruction instruction)
    {
        Parent = parent;
        Instruction = instruction;
    }
}

这样Instruction 不需要引用其父级。它可能不应该引用其父级。如果相同的InstructionBatch 的两个不同实例中怎么办?哪个是家长?

但是如果Batch 需要公开一个Instruction 并且一个对自身的引用,那么它可以通过返回一个ParentInstructionRelation 来做到这一点。或者从Batch 读取Instruction 的类可以创建这种关系。

var instructions = batch.InstructionArray
    .Select(instruction => new ParentInstructionRelation(batch, instruction));

【讨论】:

  • 这是最接近我所寻找的,也没有费心解释我需要实例化变量。谢谢斯科特
【解决方案2】:

您的代码有问题:

myBatch.instructionArray = new Instruction[3];

这只会创建一个包含 3 个 null 值的数组,而不是 Instruction 的 3 个实例。这是因为 class 是一个引用类型,它不会在此处自动实例化(structs 是,因为它们是值类型,并且在默认构造函数中初始化它们的所有值,然后调用该构造函数)。您仍然必须在将它们传递给您的方法之前创建这些指令,因为您实际上只是传递了null

那么,在创建Instruction的实例时,只需将父级作为参数传递,并在类中记住,像这样:

class Instruction
{
    public Instruction(Batch parent)
    {
        Parent = parent;
    }

    public Batch Parent { get; private set; }
    public string InstructionUID { get; set; } // Please start properties with an uppercase letter
}

这样,您以后可以访问Instruction 实例所属的Batch 实例。

Batch myBatch = new Batch();
myBatch.InstructionArray = new Instruction[3];
// TODO: Create the instances here, the array is just null null null now!
myBatch.InstructionArray[0] = new Instance(myBatch); // example
SomeFunc(myBatch.InstructionArray[0]);

public void SomeFunc(Instruction instruction)
{
    Console.Write(instruction.Parent.BatchUID)
}

如果这是一个好的设计是另一个问题,Instruction 内部可能有 SomeFunc 的东西,但我不确定该项目最终应该实现什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多