2013-01-25 3 views
4

이것은 근본적인 질문이므로 아마추어 적이라는 이유로 용서해주십시오.C#에서 두 객체의 평등 비교

사례 1 :

Employee _emp1 = new Employee(); 
Employee _emp2 = _emp1; 
_emp1.Equals(_emp2) ==> RETURNS a True !! 

Case2 :

Employee _emp1 = new Employee(); 
Employee _emp2 = new Employee(); 
_emp1.Equals(_emp2) ==> RETURNS a False !! 

당신이 나에게 메모리 매핑 및 할당 관점의 interms 위의 비교 방법과 이유를 설명 할 수 있을까요?

+3

사례 1을 놀라게합니까? C++ 배경? –

+0

@Damien_The_Unbeliever 나는 그렇게 생각한다. 빙고 !! – Cris

+1

-1 미안하지만 나는 SO가이 수준의 질문에 대한 장소라고 생각하지 않는다. 이런 종류의 일은 MSDN 및 블로그의 광고 nauseum에 적용되었습니다. – DeanOC

답변

3
Employee _emp1 = new Employee(); 

매번 작업을 수행 할 수 있습니다.

는 _emp1가

(1212)는 이제

Employee _emp2 = new Employee(); 

그래서 다시 새 값 _emp2 힙에서 1414 말 두 번째 문이 있다고 가정 힙을 가리키는 메모리의 값을 의미합니다.

그래서 _emp1.Equals (_emp2)가 false를 반환하는 이유입니다. 당신이

_emp1 = _emp2 

을 말할 때

당신은 모두 같은 값을 할당한다.

3

"이 사과는 조에 속합니다.이 배는 같은 사람에게 속합니다.이 사과 주인은이 배 주인과 동일한 사람입니까? 예."

"이 사과는 수잔에 속합니다.이 사과 주인은이 배 소유자와 같은 사람입니까? 아니요, 둘 다 수잔이라고 부르는 경우가 있습니다."

2

고유 한 Equals 메서드를 만들어야합니다. 기본적으로 EqualsObject 클래스에서 호출됩니다.이 두 참조가 하나의 객체를 가리키는 지 (즉, Object.ReferenceEqual(object, object))

9

간단히 말해서 기본 비교자는 객체 인스턴스를 비교합니다. 첫 번째 예에서

  • , _emp1_emp2 모두 사실 Employee 따라서 Equals 반환의 동일한 인스턴스를 가리키는.

  • 두 번째 예제에서는 두 개의 개체 인 _emp1_emp2을 두 개의 다른 개체로 만듭니다. 따라서 Equals은 false를 반환합니다. 생성자를 복사


참고 암시 적으로 참조 유형 호출되지 있습니다. 당신이해야 할 일 있었 :

Employee _emp1 = new Employee(); 
Employee _emp2 = new Employee(_emp1); //or _emp1.Clone() if that is implemented 

다음 Equals 그들은 두 개의 고유의 객체가 거짓 이후 반환하는 기본 비교기를 사용하여.

또한이 동작은 이 아니며 값 유형의 경우이 아닙니다. (당신이해야으로) EqualsCompareTo의 기본 동작을 재정의


또한 당신은 모든 위의 논쟁, 될 경우.표준 기술 (조금 가정)이 될 수 있습니다

public bool Equals(object rhs) 
{ 
    var rhsEmployee = rhs as Employee; 
    if(rhsEmployee == null) return false; 

    return this.Equals(rhsEmployee); 
} 

public bool Equals(Employee rhs) 
{ 
    return this.EmployeeId == rhs.EmployeeId; 
} 

추가 읽기 :

+0

첫 번째 글 머리에 말은 다음과 같은 의미입니다. _emp1과 _emp2는 모두 동일한 메모리 위치를 가리 킵니다. 두 번째 _emp1 및 _emp2에서 두 개의 다른 메모리 위치를 가리 킵니다. 글쎄, 스택, 힙과 관련이 있나요 ?? –

+1

@ LetsKickSomeAssin.net 의미 상으로는 똑같습니다. 그러나 Managed 세계에서는 일반적으로 직접 제어 할 수 없기 때문에 직접적으로 메모리에 대해 이야기하는 것을 피하는 경향이 있습니다. 그러나 예, 두 개의 포인터 값을 비교하는 ['Object.ReferenceEquals'] (http://msdn.microsoft.com/en-us/library/system.object.referenceequals.aspx)를 확인하고 있습니다. –

+0

컴파일러가'null '을'bool'로 변환하는 것을 거부하기 때문에 이것은 컴파일되지 않습니다. 다른 인스턴스가'Employee'가 아니면'Equals'는'false'를 반환해야합니다. – Nuffin

1

Employee은 자체의 .Equals() 메소드를 구현하지 않으며 참조를 비교하는 것만으로 Object.Equals()을 사용합니다. 사례 1에서는 할당시 두 참조가 동일하게됩니다.

Employee 개체를 내부 속성으로 비교하려면 해당 속성 값이 모두 일치하면 true를 반환하는 고유 한 .Equals() 메서드를 구현하고, 그렇지 않으면 false를 반환해야합니다.

1

직원의 두 개의 별도 인스턴스를 동일시 할 수있는 방법이 없으므로 별도의 인스턴스이므로 동일한 지 여부를 동일시하는 방법이 필요합니다. 하나 인 경우 인스턴스가 같고 _emp2_emp1입니다. IEquatable<T> 인터페이스를 구현하면됩니다.

public class Employee : IEquatable<Employee> 
{ 
    public int Id { get; set; } 

    public bool Equals(Employee other) 
    { 
    return other.Id == Id; 
    } 
} 

그런 다음 힙 및 스택에 할당 된 새로운 메모리를 가지고 당신이 new Employee()이이

Employee e = new Employee() { Id = 1 }; 
Employee e2 = new Employee() { Id = 1 }; 
//Returns true 
bool b = e.Equals(e2); 
1

Employee _emp1을 쓸 때 Employee 인스턴스를 포함하는 다른 메모리 조각에 포인터를 저장하는 데 필요한 메모리를 할당합니다.

new Employee();은 Employee 인스턴스로 채우는 새 메모리 조각을 할당하고이 메모리의 주소 (포인터)를 반환합니다. 예를 들어, 1234567을 가정 해 봅시다. Employee _emp1 = new Employee();을 실행 한 후 _emp1은 1234567이고, 메모리는 1234567이며 직원이 포함되어 있습니다.

그런 다음 Employee _emp2 = _emp1;을 실행하면 1234567과 동일한 Employee (_emp2) 인스턴스가 포함 된 메모리 조각에 주소를 포함 할 수있는 메모리가 생성됩니다.이 방법을 사용하면 _emp1.Equals(_emp2)을 실행할 때 두 vars가 동일한 메모리를 가리 키므로 결과가 true입니다.

두 번째 경우에는 또 다른 인스턴스 인 Employee가 만들어져 다른 메모리에 저장됩니다 (예 : 7654321).이 주소는 _emp1과 다른 _emp2에 할당됩니다.