== 운영자를 과부하해야합니까?
-
08-07-2019 - |
문제
어떻게 ==
운영자는 C#에서 실제로 작동합니까? 클래스의 객체를 비교하는 데 사용된다면 ㅏ, 그것은 모든 것을 일치 시키려고 노력할 것입니다 ㅏ의 속성, 아니면 동일한 메모리 위치 (또는 다른 것)에 대한 포인터를 찾을 수 있습니까?
가상의 예를 만들어 봅시다. 트위터 API를 사용하는 응용 프로그램을 작성하고 있습니다. 트위터 클래스, 단일 트윗의 모든 속성이있는 클래스 : 텍스트, 발신자, 날짜 및 시간, 출처 등. 클래스 객체를 비교하려면 클래스 트위터 동등성을 위해서만 사용할 수 있습니까?
Tweet a, b;
if (a == b)
{
//do something...
}
그럴 것입니다 모든 속성의 동등성을 확인하십시오 의 트위터 사이의 수업 ㅏ 그리고 비?
그렇지 않다면 올바른 접근 방식은 과부하가 될 것입니다 ==
운영자 모든 필드의 동등성을 명시 적으로 확인하려면?
업데이트: 처음 두 가지 답변에서 다음과 같이 가정 할 때 제가 옳습니다.
- 만약
==
운영자 또는 동등합니다 메소드는 클래스에 대해 과부하되지 않습니다==
연산자 물체 클래스가 사용됩니다. - 그만큼
==
연산자 물체 메모리 위치의 평등을 수업 검사합니다. - 나는 과부하해야한다
==
연산자 또는 동등합니다 이 작업을 수행하는 방법. - 오버로드에서는 수동으로 속성의 동등성을 확인해야합니다. 반자동으로 반자동으로 할 수있는 방법이 없습니다., 오른쪽?
업데이트 #2 : Yuriy는 ==
운영자 반사. 이 작업은 어떻게 할 수 있습니까? 샘플 코드 좀 주시겠습니까? 감사!
해결책
MSDN은 좋은 것을 가지고 있습니다 예시 그것을하는 방법 :
public override bool Equals(object o)
{
try
{
return (bool) (this == (DBBool) o);
}
catch
{
return false;
}
}
그런 다음 ==와! = :
// Equality operator. Returns dbNull if either operand is dbNull,
// otherwise returns dbTrue or dbFalse:
public static DBBool operator ==(DBBool x, DBBool y)
{
if (x.value == 0 || y.value == 0) return dbNull;
return x.value == y.value? dbTrue: dbFalse;
}
// Inequality operator. Returns dbNull if either operand is
// dbNull, otherwise returns dbTrue or dbFalse:
public static DBBool operator !=(DBBool x, DBBool y)
{
if (x.value == 0 || y.value == 0) return dbNull;
return x.value != y.value? dbTrue: dbFalse;
}
그리고 gethash 방법을 과부하시키는 것을 잊지 마십시오.
편집하다:
비교에서 반사를 사용하기 위해 다음의 빠른 샘플을 썼습니다. 이것은 훨씬 더 포괄적이어야합니다. 사람들이 나를 원한다면 다음과 같은 블로그를 시도 할 수 있습니다.
public class TestEquals
{
private int _x;
public TestEquals(int x)
{
this._x = x;
}
public override bool Equals(object obj)
{
TestEquals te = (TestEquals)obj;
if (te == null) return false;
foreach (var field in typeof(TestEquals)
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
if (!field.GetValue(this).Equals(field.GetValue(te)))
return false;
}
return true;
}
}
다른 팁
참조 유형의 경우 두 가지의 기본 구현 ==
운영자와 Equals()
메소드는 단순히 두 객체가 동일한 참조를 가지므로 동일한 인스턴스인지 확인합니다.
두 개의 다른 객체의 내용을 확인하려면 동일하다면 코드를 작성하여 직접 수행해야합니다. 반사와 관련이있을 것입니다 ( mbunit 테스트 프레임 워크는이 라인을 따라 무언가를합니다) 그러나 성능이 큰 페널티와 어쨌든 기대했던 일을 할 수 없을 가능성이 높으며 구현해야합니다. ==
또는 Equals
그리고 GetHashCode
손으로.
적절한 접근법은 설명대로 == 연산자 외에 트윗 클래스의 평등 메소드를 과부하입니다. 여기.
이 트윗 클래스의 모든 속성의 동등성을 확인하여 A와 B 사이의 동등성을 확인합니까?
아니
그렇지 않은 경우, 올바른 접근 방식은 == 연산자에게 모든 필드의 동등성을 명시 적으로 점검하기 위해 과부하하는 것입니까?
과부하 할 수 있습니다 == 연산자 또는 과부하 동등합니다 기능.
편집하다
@yuriy는 모든 비 공개 변수를 컴파일하는 데 좋은 예를 제공했습니다. 예를 썼기 때문에 여기에 있습니다 (광산 비교 속성)
class TwitterItem
{
private string myValue = "default value";
public string Value1
{
get { return myValue; }
set { myValue = value; }
}
public string Value2
{
get { return myValue; }
set { myValue = value; }
}
public string Value3
{
get { return myValue; }
set { myValue = value; }
}
public override bool Equals(object obj)
{
if (base.Equals(obj)) return true;
Type type = typeof(TwitterItem);
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
if (false == property.GetValue(this, null).Equals(property.GetValue(obj, null)))
return false;
}
return true;
}
}
반사를 사용하여 속성을 비교할 수 있습니다.
var a = new Entity() { Name = "test", ID = "1" };
var b = new Entity() { Name = "test", ID = "1" };
var c = new Entity() { Name = "test", ID = "2" };
System.Diagnostics.Debug.WriteLine(a.Equals(b));//Returns true
System.Diagnostics.Debug.WriteLine(a.Equals(c));//Returns false
public class Entity
{
public string Name { get; set; }
public string ID { get; set; }
public override bool Equals(object obj)
{
var t = obj.GetType();
foreach (var p in t.GetProperties())
{
if (t.GetProperty(p.Name).GetValue(obj, null) != t.GetProperty(p.Name).GetValue(this, null))
return false;
}
return true;
}
}