在同一个类的构造函数中传递类的对象

时间:2017-11-06 19:45:32

标签: c#

如何用StudentId = 1和Name =“Alex”

初始化这样的类
class Student
{
    public int StudentId { get; set; }
    public string Name { get; set; }

    public Student(Student student)
    {
        StudentId = student.StudentId;
        Name = student.Name;
    }
}
class Program
{
    static void Main(string[] args)
    {
        Student s = new Student()
    }
}

6 个答案:

答案 0 :(得分:7)

您可以添加另一个手动提供值的构造函数:

public Student(int id, string name)
{
    StudentId = id;
    Name = name;
}

初始代码不起作用的原因是,当您创建需要相同类型的另一个实例的对象时,依赖关系链会上升到无穷大,您永远不会有起点。

通过使用手动构造函数,您可以手动创建起点,换句话说,是其他对象可以依赖的初始对象。因此,您消除了无限的依赖链。

答案 1 :(得分:3)

你不能像这样初始化一个类:它需要一个自己的实例才能被初始化,呈现鸡与蛋的问题。

请注意,您无法构造派生类并将其传递给Student的构造函数,因为派生类必须调用复制构造函数。

解决此问题的唯一方法是添加一个不同于你的构造函数,并将其命名为:

public Student(int id, string name) {
    StudentId = id;
    Name = name;
}

或添加默认构造函数,并使用属性初始化程序调用它:

public Student() {}
...
var student = new Student {Id = 1, Name = "Alex" };

答案 2 :(得分:1)

让一个类的唯一构造函数需要一个类的实例是没有意义的,并且你肯定需要一些其他类型的构造函数才能使用一个(否则你永远不能创建那个初始实例)

然而,有一件事是有道理的,就是让static method从现有的类中创建一个新的类实例。

下面的示例没有定义任何显式构造函数,因此使用默认构造函数并显式设置类值:

class Student
{
    public int StudentId { get; set; }
    public string Name { get; set; }

    public static Student CreateFrom(Student student)
    {
        return new Student { StudentId = student.StudentId, Name = student.Name };
    }
}

要使用此方法,您首先要创建一个学生:

var studentOne = new Student { StudentId = 1, Name = "Bob"};

然后,要从这个创建一个新学生,我们可以调用我们的静态方法:

var studentTwo = Student.CreateFrom(studentOne);

但现在我们有两名学生拥有相同的身份证。也许这不是我们想要的,所以最好是从私有静态支持字段自动设置只读StudentId。我们可以使用lock对象来确保我们不会为多个学生分配相同的ID。我们也可以覆盖ToString方法,以便显示学生的ID和姓名:

class Student
{
    // This lock object is used to ensure we don't 
    // assign the same Id to more than one student
    private static readonly object IdLocker = new object();

    // This keeps track of next available student Id
    private static int nextStudentId;

    // Read only
    public int StudentId { get; }

    public string Name { get; set; }

    // Default constructor automatically sets the student Id
    public Student()
    {
        lock (IdLocker)
        {
            // Assign student id and incrment the next avaialable
            StudentId = nextStudentId;
            nextStudentId++;
        }
    }

    public static Student CreateFrom(Student student)
    {
        return new Student { Name = student.Name };
    }

    public override string ToString()
    {
        return $"Student {StudentId}: {Name}";
    }
}

现在我们不需要设置id,我们可以看到它会自动为我们增加:

private static void Main()
{
    var studentOne = new Student { Name = "Bob" };
    var studentTwo = Student.CreateFrom(studentOne);

    Console.WriteLine(studentOne);
    Console.WriteLine(studentTwo);

    Console.Write("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

<强>输出

enter image description here

答案 3 :(得分:0)

您需要一些初始化对象而不使用该构造函数的方法。因此,使用具有内联初始化的默认构造函数来创建初始学生,然后允许您使用已存在的实例创建其他Student个对象。

using System;

public class Program
{
    public static void Main()
    {
        var s = new Student {
            StudentId = 1,
            Name = "Alex"
        };

        var s2 = new Student(s);

        Console.WriteLine(s2.StudentId);
        Console.WriteLine(s2.Name);
    }
}

class Student
{
    public int StudentId { get; set; }
    public string Name { get; set; }

    public Student() {}

    public Student(Student student)
    {
        StudentId = student.StudentId;
        Name = student.Name;
    }
}

<强> DotNetFiddle

答案 4 :(得分:0)

您的代码令人困惑,您只需要传递构造函数而不是对象,但是您尝试这样做的方式,您需要在Main程序中创建的实例上设置第一个属性,然后传递实例喜欢,但你也需要添加一个无参数的构造函数:

class Student
{
    public int StudentId { get; set; }
    public string Name { get; set; }

    // Note: parameterless constructor here
    public Student()
    {


    }

    public Student(Student student)
    {
        StudentId = student.StudentId;
        Name = student.Name;
    }
}
static void Main(string[] args)
{
        Student s = new Student(); // parameter less constructor
        s.StudentId = 1;
        s.Name = "Alex";

       Student s2 = new Student(s);
}

但请注意这将使您的代码编译甚至工作,但这对于做简单的事情并没有内存效率来说是太多额外的东西,因为我们创建了一个额外的实例,这是根本不需要。

所以你只需要在StudentIdName的构造函数中有参数,如S. Tarik's answer所示。

这样你的构造函数就像:

public Student(int studentId, string name)
{
    StudentId = studentId;
    Name = name;
}

希望它能让您了解如何解决这个问题。

谢谢!

答案 5 :(得分:0)

public class Student
{ 
  public int Id {get; set;}
  public string Name {get; set; }

  public Student(object o) 
  {
    Student student = o as Student;
    if (student != null)
    {
       Id = student.Id;
       Name = student.Name;
    }

    // other cases to build a User copy
    string json = o as string;
    if (json != null) 
    {
         Student student = JsonConvert.Deserialize<Student>(json);
         Id = student.Id;
         Name = student.Name;
    }

  }

  public Student() 
      : this(null)
  {

  }

  public Student(int id, string name) 
      this(null)
  {
      Id = id;
      Name = name;
  }
}



static void Main(string[] args) 
{
     Student student = new Student(7634, "Jim");

     // build a copy
     Student copy = new Student(student);
}