C# 具有未知参数的构造函数
我最近开始用C语言编程,在PHP上度过了我的大部分时间 在PHP中,我可以这样做:C# 具有未知参数的构造函数,c#,class,oop,inheritance,constructor,C#,Class,Oop,Inheritance,Constructor,我最近开始用C语言编程,在PHP上度过了我的大部分时间 在PHP中,我可以这样做: class User { public __construct($UserId) { // Do stuff } } class Employee extends User { public __construct($EmployeeId) { // Look up the UserId connected to $EmployeeId
class User
{
public __construct($UserId)
{
// Do stuff
}
}
class Employee extends User
{
public __construct($EmployeeId)
{
// Look up the UserId connected to $EmployeeId
$UserId = hypothetical_get_user_id_func($EmployeeId);
parent::__construct($UserId);
}
}
但是,在C中,我似乎没有这种可能性,因为在$UserId进入第一个构造函数之前,我似乎必须知道它
public class User
{
public User(int UserId)
{
// Do stuff
}
}
public class Employee : User
{
public Employee(int EmployeeId) : base(***) // I don't know this value yet?
{
// This is where I would find the User Id, and would like to pass
// it to the User class constructor.
}
}
有什么方法可以实现我在C语言中的目标吗
基本上,将值传递给主对象的构造函数,主对象在其自身的主体中确定要传递给基类的值。某些语言允许您从派生构造函数中显式调用基类构造函数
public class User
{
public User(int UserId)
{
// Do stuff
}
}
public class Employee : User
{
public Employee(int EmployeeId) : base(***) // I don't know this value yet?
{
// This is where I would find the User Id, and would like to pass
// it to the User class constructor.
}
}
C不是这样一种语言
在这种情况下,由于EmployeeId与UserId不同,并且是在派生类构造函数中计算的,因此必须从Employee构造函数中设置它,而不是将其作为参数传递给基类构造函数
public class User
{
public User(int UserId)
{
// Do stuff
}
}
public class Employee : User
{
public Employee(int EmployeeId) : base(***) // I don't know this value yet?
{
// This is where I would find the User Id, and would like to pass
// it to the User class constructor.
}
}
UserId基类中的备份存储需要设置为受保护,或者您需要提供受保护的属性或方法来设置它。您可以在构造函数中调用静态方法。但是非常不标准
public class User
{
public User(int userId)
{
// Do stuff
}
}
public class Employee : User
{
public Employee(int employeeId) : base(GetUserId(employeeId))
{
}
public static int GetUserId(int employeeId)
{
return employeeId - 5;
}
}
您可以重构为共享函数:
public class User
{
protected User() {}
public User(int userId)
{
Init(userId);
}
protected void Init(int userId)
{
// Do stuff
}
}
public class Employee : User
{
public Employee(int employeeId)
{
// find user Id here
Init(userId);
}
}
注意,我将参数名称的大小写改为更标准的小写
我习惯于将db表中的Id主键传递给对象构造函数,然后从构造函数中的db获取数据
public class User
{
public User(int UserId)
{
// Do stuff
}
}
public class Employee : User
{
public Employee(int EmployeeId) : base(***) // I don't know this value yet?
{
// This is where I would find the User Id, and would like to pass
// it to the User class constructor.
}
}
不要那样做。类不应该依赖外部数据源来创建自身的实例。创建一个单独的类存储库,工厂,无论从数据库中提取数据,并填充空白对象的属性。
将数据库逻辑放在类的构造函数中可以防止独立于数据源进行测试 您想做的事情不是,也可能不应该是-谢谢,PHP是可能的,但是像这样的事情就足够了:
public class User
{
protected User() {
// Do things here
}
public User(int UserId)
{
Init(UserId);
}
protected void Init(int UserId) {
// Do stuff
}
}
public class Employee : User
{
public Employee(int EmployeeId) : base()
{
int UserId;
// Find UserId
Init(UserId);
}
}
关注点分离
其他答案没有理解的是PHP和C有非常不同的编码标准
PHP中的一个常见模式是
class User
{
public __construct($UserId)
{
// Do stuff
}
}
class Employee extends User
{
public __construct($EmployeeId)
{
// Look up the UserId connected to $EmployeeId
$UserId = get_userid_from_database($EmployeeId);
parent::__construct($UserId);
}
}
但在C语言中,这绝对不会被认为是一个好的设计
在.net中实现此功能的典型方法将更接近
public class User
{
public User(int userId)
{
// Do stuff
}
}
public class Employee : User
{
public Employee(int employeeId, int userId) : base(userId) // I don't know this value yet?
{
// This is where I would find the User Id, and would like to pass
// it to the User class constructor.
}
}
public class EmployeeRepository
{
public Employee GetEmployee(int employeeId)
{
using(var connection = new SqlConnection(..)
{
//blah blah blah
return new Employee(employeeId, userId);
}
}
}
要点是Employee可能在没有数据库的情况下使用,例如在单元测试中。使用静态方法实例化类怎么样
public class User
{
public User(int UserId)
{
// Do stuff
}
}
public class Employee : User
{
private Employee(int userID) : base(userID) { }
public static Employee GetEmployee(int employeeID)
{
var userID = GetUserIDFromEmployeeID(employeeID);
return new Employee(userID);
}
}
然后在您的呼叫代码中,您将:
var employee = Employee.GetEmployee(someValue);
您必须将userId作为另一个参数。这是不可能的。但您可以调用静态方法并传递其结果。正如SLaks所说,这是不可能的。但是有很好的理由。构造函数中不应包含业务逻辑。你所说的听起来更像是一个DAL/工厂。在C语言中,我们鼓励坚实的设计原则,而您正在尝试的是打破坚实的关注点部分的分离。很遗憾,我会…>\u