【问题标题】:Passing list as an argument将列表作为参数传递
【发布时间】:2018-01-07 17:37:45
【问题描述】:

我似乎对对象的引用有一个意外的问题。我的代码有一个草稿:

// file 1
List<A> list1;
List<B> list2 = function(list1);
//file 2
public static List<B> function(List<A> input)
{
    list<B> output = new List<B>();
    for (int i ...)
    {
        output.Add(new B(input[i]));
    {
    return output;
}
// file 1
list1[1].FieldOfAObject = 10; // I change an object from list1
WriteLine(list2[1].objectA.FieldOfAObject); // it is not changed

在我看来,由于 list1 是一个类,A 是一个类并且它们是通过引用传递的,所以在 function 中创建并分配给 list2 的类型 B 的对象应该保留对对象的引用list1.

编辑 真实代码:

public void PrintCylinder(Camera camera, Cylinder cylinder, Bitmap Bitmap, double bitmapWidth, double bitmapHeight, PrintArguments pa)
    {
        ...
        List<AffineCoordinates> verticesToPritOnScreen = new List<AffineCoordinates>(); // out list1
        foreach (var vertex in cylinder.Mesh.MeshVertices)
        {
            AffineCoordinates newVertex = PVM * vertex;
            verticesToPritOnScreen.Add(newVertex); // list1 is being filled here
        }

        List<Face> FaceList = MeshGridGenerator.GenerateCylinderGrid(verticesToPritOnScreen, cylinder.D); // our list2

// CHANGES BENEATH ARE NOT VISIBLE IN FaceList objects
        for (int i = 0; i < verticesToPritOnScreen.Count; ++i)
        {
            // project to NDC
            verticesToPritOnScreen[i] = verticesToPritOnScreen[i] / verticesToPritOnScreen[i].W;
            // project to screen space
            verticesToPritOnScreen[i].X = (verticesToPritOnScreen[i].X + 1) * bitmapWidth / 2;
            verticesToPritOnScreen[i].Y = (verticesToPritOnScreen[i].Y + 1) * bitmapHeight / 2;
            verticesToPritOnScreen[i].Z = (verticesToPritOnScreen[i].Z + 1) / 2;
            verticesToPritOnScreen[i].W = 1;
        }

        ...
    }
// our function (from MeshGridGenerator class)
public static List<Face> GenerateCylinderGrid(List<AffineCoordinates> vertices, int D)
    {
        List<Face> FaceList = new List<Face>();

        for (int i = 1; i <= D; ++i)
        {
            // upper base
            FaceList.Add(new Face(vertices[0], vertices[i], vertices[i % D + 1]));
            // bottom base
            FaceList.Add(new Face(vertices[vertices.Count - 1], vertices[i % D + 1 + D], vertices[i + D]));
            // side wall's upper triangle
            FaceList.Add(new Face(vertices[i], vertices[i + D], vertices[i % D + 1]));
            // side wall's bottom triangle
            FaceList.Add(new Face(vertices[i % D + 1], vertices[i + D], vertices[i % D + 1 + D]));
        }

        return FaceList;
    }
// our B class
public class Face
{
    public AffineCoordinates[] vertices;

    public bool AreVerticesClockwise
    {
        get
        {
            double sum = 0.0;
            for (int i = 0; i < 3; ++i)
            {
                sum += (vertices[(i + 1) % 3].X - vertices[i].X) * (vertices[(i + 1) % 3].Y + vertices[i].Y);
            }
            return sum < 0;
        }
    }

    public Face(params AffineCoordinates[] ver)
    {
        vertices = new AffineCoordinates[3];
        vertices[0] = ver[0];
        vertices[1] = ver[1];
        vertices[2] = ver[2];
    }
}

我知道这是很多颂歌,所以我不想发布它。

【问题讨论】:

  • 你能显示B的构造函数吗?
  • 这里没有人能猜到 B 类型的行为方式,因此如果您需要帮助找出它为什么不像您预期​​的那样运行,您必须发布它。此外,发布 real 代码,因为代码无法编译(定义不完整,大括号放置不正确)等,因此很难相信这甚至是您真实代码的缩减版本。如果您需要实际代码方面的帮助,请发布您的实际代码,或者更好,发布minimal reproducible example

标签: c# list reference


【解决方案1】:

这段代码打印出“20”,我认为你在追求什么?

 public class A
 {
      public int Value;
 }

 public class B
 {
      public A objectA;
      public B(A obj)
      {
            objectA = obj;
      }
 }
 class Program
 {
      public static List<B> function(List<A> input)
      {
            List<B> output = new List<B>();
            foreach  (var i in input)
            {
                 output.Add(new B(i));
            }
            return output;
      }
      static void Main(string[] args)
      {
            List<A> listA = new List<A>();
            listA.Add(new A { Value = 10 });
            List<B> listB = function(listA);
            listA[0].Value = 20;
            Console.WriteLine(listB[0].objectA.Value);
      }
 }

【讨论】:

  • 为什么要实例化listB 来替换它为function(listA)?另外,A.ValueB.objectA 都应该是属性,而不是字段
  • 代码的重点是证明 B 包含对 A 的引用,这是 OP 遇到的问题。它可以在很多方面进行改进...... :)
  • 如果您向刚刚学习的人展示不良做法,他们会学习不良做法。我见过太多次生产代码,比如a = new List&lt;T&gt;(); a = GetData();
  • 欢迎发布更好的答案
  • @HansKilian 你的代码是我所拥有的更简单的版本,我不知道为什么我的代码会失败。
猜你喜欢
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 2018-06-03
  • 2013-11-13
相关资源
最近更新 更多