1

まず最初に。私は次のクラスを持っています:

class Employee
{
    private int employeeID;
    private string firstName;
    private string lastName;
    private bool eligibleOT;
    private int positionID;
    private string positionName;
    private ArrayList arrPhone;
    public IList<Sector> ArrSector {get; private set;}

    //the constructor method takes in all the information of the employee
    public Employee(int empID, string fname, string lname, bool elOT, int pos, string posname)
    {
        employeeID = empID;
        firstName = fname;
        lastName = lname;
        eligibleOT = elOT;
        positionID = pos;
        positionName = posname;
        arrPhone = new ArrayList();
        ArrSector = new List<Sector>();
    }

    //the constructor method takes in the employee id, the first name and the last name of the employee
    public Employee(int empid, string firstname,string lastname)
    {
        employeeID = empid;
        firstName = firstname;
        lastName = lastname;
    }

    //overtides the first name and the last name as a string.
    public override string ToString()
    {
        return firstName +" "+lastName;
    }



    public int EmployeeID
    {
        get { return employeeID; }
        set { employeeID = value; }
    }

    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }

    public string LastName
    {
        get { return lastName; }
        set { lastName = value; }
    }

    public bool EligibleOT
    {
        get { return eligibleOT; }
        set { eligibleOT = value; }
    }

    public int PositionID
    {
        get { return positionID; }
        set { positionID = value; }
    }

    public string PositionName
    {
        get { return positionName; }
        set { positionName = value; }
    }

    public ArrayList ArrPhone
    {
        get { return arrPhone; }
        set { arrPhone = value; }
    }



    // The function assigns all the variables associated to the employee to a new object.
    public static object DeepClone(object obj)
    {
        object objResult = null;
        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            ms.Position = 0;
            objResult = bf.Deserialize(ms);
        }
        return objResult;
    }

   //Memento pattern is used to save the employee state.
   //The changes will be rolled back if the update button not clicked
    public class Memento : IMemento
    {
        private Employee originator = null;
        private int employeeID;
        private string firstName;
        private string lastName;
        private bool eligibleOT;
        private int positionID;
        private string positionName;
        private ArrayList arrPhone;
        private IList<Sector> arrSector;

        public Memento(Employee data)
        {
            this.employeeID = data.EmployeeID;
            this.firstName = data.FirstName;
            this.lastName = data.LastName;
            this.eligibleOT = data.EligibleOT;
            this.positionID = data.PositionID;
            this.positionName = data.PositionName;
            this.arrPhone = data.ArrPhone;

            this.originator = data;
            this.arrSector = Extensions.Clone<Sector>(data.ArrSector);
        }

}

WinformでCシャープを使用しています。私のアプリケーションのフロント エンドには、従業員の最初の名前を持つ左端側にリスト ボックスがあります。左側には、リスト ボックスで選択された従業員に対応するさまざまなテキスト ボックスがあります。従業員を選択するたびに、従業員 ID、名前、役職などの属性がこれらのフィールドに表示されるようにコーディングしました。

ユーザーが従業員の属性を変更した場合、更新ボタンをクリックしてデータベースを変更する必要があります。本当の問題は、ユーザーが選択した従業員のフィールドを変更し、更新ボタンをクリックせずに別の従業員を選択した場合、ポップアップ ボックスを表示して、ユーザーが別の従業員を選択した場合、すべての変更が失った。

このため、従業員の以前の状態を保持するために momento クラスを作成しました。== 演算子のオーバーロードも試みました

        public static bool operator ==(Employee e, Memento m)
        {
            return ((e.employeeID == m.employeeID) &&
               (e.firstName == m.firstName) &&
               e.lastName == m.lastName &&
               e.eligibleOT == m.eligibleOT &&
               e.positionID == m.positionID &&
               e.positionName == m.positionName &&
               e.arrPhone == m.arrPhone &&
               e.ArrSector == m.arrSector);
        }

        public static bool operator !=(Employee e, Memento m)
        {
            return (e.employeeID != m.employeeID);
        }

私の考えは、2 つのオブジェクトを比較することでしたが、成功しませんでした。どうすればいいですか??変更が行われた場合にポップアップを表示するにはどうすればよいですか??ポップアップを表示するコードをどこに配置すればよいですか?

4

2 に答える 2

2

警告の一言...一般的に、==and!=演算子で異なるロジックを使用することはお勧めできません。両方==を同時に持つことができるのは、やや直感的ではあり!=ませんfalse

if(!(a == b) && !(a != b))
{
    // head explodes
}

それはさておき、比較コードでクラスが(または他の親クラス)Employeeとして参照されていると思います。object多分このようなもの:

if(listBox1.SelectedItem != currentMemento)
{
    ...
}

この場合、コンパイラは!=をカスタム実装にバインドしていません。それを強制するためにキャストlistBox1.SelectedItemします。Employee

if((Employee)listBox1.SelectedItem != currentMemento)
{
    ...
}

ただし、この問題を解決するには、他にも多くの方法があります。

  • boolテキストフィールドのデータが変更されたときに設定される を使用して、GUI 側で完全に実装し、true従業員を変更するときにそのフラグを確認します
  • IComparableまたはIEquatableインターフェイスを実装する
  • and/orクラスのEqualsメソッドをオーバーライドするEmployeeMemento

(2 番目のオプションを使用する場合は、通常、3 番目のオプションも完了することをお勧めします)

これはあなたができることの例です(私はあなたがListBox名前を持っていて、関数でイベントにlistBox1添付されていると仮定しています):SelectedIndexChangedlistBox1_SelectedIndexChanged

private Employee lastSelectedEmployee;
private Memento selectedMemento;

void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    Employee selectedEmployee = (Employee)listBox1.SelectedItem;

    if(lastSelectedEmployee != null && lastSelectedEmployee != selectedEmployee)
    {
        if(/*changes exist*/)
        {
            if(/*cancel changes*/)
            {
                listBox1.SelectedItem = lastSelectedEmployee;

                return;
            }
        }
    }

    lastSelectedEmployee = selectedEmployee;
    selectedMemento = //create the memento based on selectedEmployee;
}

私がコメントを残した領域については、独自のロジックを提供する必要がありますが、アイデアは非常に単純です。

于 2010-01-28T13:48:53.280 に答える
-1

IComparable インターフェイスを見てください。このような比較を行うために必要なメソッドを実装する必要があります。KB 記事、うまくいけば英語に変わりますが、私の PC では常にドイツ語になります。

-さ

于 2010-01-28T13:36:46.543 に答える