我们可以在索引器中限制set运算符的索引器数量吗?

时间:2016-08-04 11:08:35

标签: c#

对于下面的索引器,它应该是这样的:get {}用户可以传递employeeid或firstname,而set {}只能传递employeeid。

以下是代码:

public Employee this[int employeeid = 0,string firstname = ""]
{
    get
    {
        if (employeeid != 0)
        {
            return Employees.FirstOrDefault(emp => emp.No == employeeid);
        }
        else
        {
            return Employees.FirstOrDefault(emp => emp.FirstName == firstname);
         }
    }
    set
    {
        if (employeeid == value.No)
        {
            Employees.FirstOrDefault(emp => emp.No == employeeid).FirstName = value.FirstName;
            Employees.FirstOrDefault(emp => emp.No == employeeid).LastName = value.LastName;
        }
        else
        {
            ArgumentException argEx = new ArgumentException("Falied to update");
            System.Windows.Forms.MessageBox.Show(argEx.Message);
        }
    }
}

我只想知道是否有任何语法限制在set操作中传递的索引器的数量和类型。 或者只是为set添加新的索引器,这显然有效。

2 个答案:

答案 0 :(得分:3)

添加新的索引器。 C#添加了索引器,以提供类似于数组的语法和用户定义的语义。您的代码提供的语义是违反直觉的,而不是像所有类似的。

例如,employee[123, "Alex"]employee[123, "Bart"]将返回相同的Employee,因为当ID和名称都存在时,ID会获胜。对于正确命名的方法,这是一件好事,例如

Employee GetEmployeeByIdOrName(int employeeid = 0,string firstname = "") {
    ...
}

多参数索引器应该将整个参数组合视为单个键,而您的实现不会这样做。

  

例如,如果函数有两个参数intstring。然后,如果用户可以提供intstring,但不能同时提供。你认为我们不需要新的函数语法来实现这一点。

今天你可以使用一对调用相同方法的重载来实现:

// The following two methods are visible to users of your object
public Employee GetEmployee(int id) {
    return GetEmployeeByIdOrName(id, null);
}
public Employee GetEmployee(string name) {
    return GetEmployeeByIdOrName(0, name);
}
// This private method provides an implementation
private Employee GetEmployeeByIdOrName(int employeeid, string firstname) {
    ...
}

答案 1 :(得分:2)

您不能在同一个索引器中为setter和getter使用不同的参数。

为了诚实,我看到你正在尝试做的事情,对于使用你班级的开发人员来说完全不清楚。

我不会使用索引器在类中通过id或名称在同一方法中查找数组内的对象。

为什么不为每个搜索条件拆分而不是两个方法(索引器):

public Employee this[int employeeid]
{
    get
    {
        return Employees.FirstOrDefault(emp => emp.No == employeeid);
    }
}

public Employee this[string firstname]
{
    get
    {
        return Employees.FirstOrDefault(emp => emp.FirstName == firstname);
    }
}

您的Set索引器完全不清楚且具有误导性。检查传递的对象是否与您正在调用索引器方法的对象具有相同的ID,然后从传递的对象更新这些值。更不用说你只更新该对象中的两个属性。这是一个糟糕的设计,而另一个明确的解决方案是:

public void UpdateEmployee(Employee updatedEmployee)
{
    if (this.No == updatedEmployee?.No)
    {
        this.FirstName = updatedEmployee.FirstName;
        this.LastName = updatedEmployee.LastName;
    }
    else
    {
        // throw
    }
}