![](/img/trans.png)
[英]Passing different objects of the same parent class to a constructor/method that hosts a generic derived class object
[英]Passing object of class in constructor of the same class
如何用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()
}
}
您可以添加另一個手動提供值的構造函數:
public Student(int id, string name)
{
StudentId = id;
Name = name;
}
初始代碼不起作用的原因是,當您創建需要相同類型的另一個實例的對象時,依賴關系鏈會上升到無窮大,您永遠不會有起點。
通過使用手動構造函數,您可以手動創建起始點,換句話說,是其他對象可以依賴的初始對象。 因此,您消除了無限的依賴鏈。
你不能像這樣初始化一個類:它需要一個自己的實例才能被初始化,呈現雞與蛋的問題。
請注意,您無法構造派生類並將其傳遞給Student
的構造函數,因為派生類必須調用復制構造函數。
解決這個問題的唯一方法是添加一個不同於你的構造函數,並調用它:
public Student(int id, string name) {
StudentId = id;
Name = name;
}
或者添加默認構造函數,並使用屬性初始值設定項調用它:
public Student() {}
...
var student = new Student {Id = 1, Name = "Alex" };
讓一個類的唯一構造函數需要一個類的實例是沒有意義的,並且你肯定需要一些其他類型的構造函數才能使用一個(否則你永遠不能創建那個初始實例)。
然而,有一點確實有意義的是使用靜態方法從現有類創建類的新實例。
下面的示例沒有定義任何顯式構造函數,因此使用默認構造函數並顯式設置類值:
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);
但是現在我們有兩個同一個Id的學生。 也許這不是我們想要的,所以最好讓一個只讀的StudentId
從私有靜態支持字段自動設置。 我們可以使用lock
對象來確保我們不會為多個學生分配相同的ID。 我們也可以覆蓋ToString
方法,以便顯示學生的Id和Name:
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();
}
產量
你需要一些方法來初始化沒有那個構造函數的對象。 因此,使用具有內聯初始化的默認構造函數來創建初始學生,然后允許您使用其現有實例創建其他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;
}
}
您的代碼令人困惑,您只需要在構造函數中傳遞參數而不是對象,但是您嘗試這樣做的方式,您需要在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);
}
但請注意 ,這將使您的代碼編譯甚至工作,但這對於執行簡單的操作而非內存效率來說是太多額外的東西,因為我們創建了一個根本不需要的額外實例。
所以你只需要在StudentId
和Name
的構造函數中有參數,如S. Tarik的答案所示。
那樣你的構造函數看起來像:
public Student(int studentId, string name)
{
StudentId = studentId;
Name = name;
}
希望它能讓您了解如何解決這個問題。
謝謝!
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.