C #에서 프리미티브의 ==와 Equals ()의 차이점은 무엇입니까?
이 코드를 고려하십시오.
int age = 25;
short newAge = 25;
Console.WriteLine(age == newAge); //true
Console.WriteLine(newAge.Equals(age)); //false
Console.ReadLine();
int
및 short
기본 유형이지만 둘 과 의 비교 ==
는 true 를 리턴하고 비교 Equals
는 false 를 리턴합니다.
왜?
짧은 답변:
평등은 복잡합니다.
자세한 답변 :
기본 요소 유형은 기본을 대체하고 object.Equals(object)
상자 object
가 동일한 유형 및 값인 경우 true를 리턴합니다 . (널링 가능 유형에 대해서도 작동합니다. 널이 아닌 널 입력 가능 유형은 항상 기본 유형의 인스턴스에 대해 상자가됩니다.)
newAge
is 이므로 동일한 값으로 boxed short 를 전달하면 short
해당 Equals(object)
메소드 만 true를 리턴합니다 . boxed를 전달 하므로 false를 반환합니다.int
대조적으로, ==
연산자는 2 int
초 (또는 1 short
초) 를 취하는 것으로 정의됩니다 long
.
당신이 그것을 호출 할 때 int
와 short
, 컴파일러는 암시 적으로 변환됩니다 short
에 int
그 결과 비교 int
값으로들.
그것을 작동시키는 다른 방법들
기본 유형 Equals()
에는 동일한 유형을 허용하는 자체 메소드 도 있습니다 .
작성 age.Equals(newAge)
하면 컴파일러 int.Equals(int)
에서 최상의 과부하를 선택 하고 암시 적으로로 변환 short
합니다 int
. true
이 메소드는 단순히 int
s를 직접 비교하기 때문에을 리턴 합니다.
short
또한 short.Equals(short)
메소드가 있지만 int
암시 적으로로 변환 short
할 수 없으므로 호출하지 않습니다.
캐스트 로이 메소드를 강제로 호출 할 수 있습니다.
Console.WriteLine(newAge.Equals((short)age)); // true
이것은 short.Equals(short)
권투없이 직접 호출 합니다. 경우 age
32767보다 큰, 그것은 오버 플로우 예외가 발생합니다.
short.Equals(object)
오버로드를 호출 할 수도 있지만 박스형 객체를 명시 적으로 전달하여 동일한 유형을 얻습니다.
Console.WriteLine(newAge.Equals((object)(short)age)); // true
이전 대안과 마찬가지로,에 맞지 않으면 오버플로가 발생합니다 short
. 이전 솔루션과 달리 short
시간과 메모리를 낭비하여 객체를 상자에 넣습니다.
소스 코드:
Equals()
실제 소스 코드의 두 가지 방법은 다음과 같습니다 .
public override bool Equals(Object obj) {
if (!(obj is Int16)) {
return false;
}
return m_value == ((Int16)obj).m_value;
}
public bool Equals(Int16 obj)
{
return m_value == obj;
}
추가 자료 :
Eric Lippert를 참조하십시오 .
이 때문에 대한 과부하 short.Equals
그은을지지 않습니다 int
. 따라서 이것을 다음이라고합니다.
public override bool Equals(object obj)
{
return obj is short && this == (short)obj;
}
obj
하지 않은 것이다 short
.. 따라서,이 거짓.
Equals에 전달하면 다음과 같이 전달 int
됩니다 .short
object
따라서이 의사 코드는 다음과 같이 실행됩니다.
return obj is short && this == (short)obj;
값 유형의 .Equals
경우 두 개체의 유형이 동일하고 값이 같아야하지만 ==
두 값이 동일한 지 테스트 만하면됩니다.
Object.Equals
http://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx
==
동일한 조건을 확인하는 데 사용되며 연산자 (부울 연산자)로 간주 될 수 있습니다. 단지 2 가지를 비교하기 위해 여기에서 유형 캐스팅이 수행되므로 데이터 유형은 중요하지 않으며 Equals
등호 조건을 확인하는 데에도 사용됩니다 그러나이 경우 데이터 유형이 동일해야합니다. N 같음은 연산자가 아닌 방법입니다.
아래는 귀하가 제공 한 것에서 가져온 작은 예이며 차이점을 간략하게 설명합니다.
int x=1;
short y=1;
x==y;//true
y.Equals(x);//false
in the above example, X and Y have same values i.e. 1, and when we use ==
, it will return true, as in case of ==
, the short type is converted to int by the compiler and the result is given.
and when we use Equals
, the comparing is done, but the type casting is not done by compiler, so false is returned.
Guys, please let me know if I'm wrong.
In many contexts where a method or operator argument is not of the required type, the C# compiler will attempt to perform an implicit type conversion. If the compiler can make all arguments satisfy their operators and methods by adding implicit conversions, it will do so without complaint, even though in some cases (especially with equality tests!) the results may be surprising.
Further, each value type such as int
or short
actually describes both a kind of value and a kind of object(*). Implicit conversions exist to convert values to other kinds of values, and to convert any kind of value to its corresponding kind of object, but the different kinds of objects are not implicitly convertible to each other.
If one uses the ==
operator to compare a short
and an int
, the short
will be implicitly converted to an int
. If its numerical value was equal to that of the int
, the int
to which it was converted will equal the int
to which it is compared. If one attempts to use the Equals
method on the short to compare it with an int
, however, the only implicit conversion which would satisfy an overload of the Equals
method would be the conversion to the object type corresponding to int
. When the short
is asked whether it matches the passed-in object, it will observe that the object in question is an int
rather than a short
and thus conclude that it cannot possibly be equal.
In general, although the compiler won't complain about it, one should avoid comparing things which are not of the same type; if one is interested in whether conversion of things to a common form would give the same result, one should perform such conversion explicitly. Consider, for example,
int i = 16777217;
float f = 16777216.0f;
Console.WriteLine("{0}", i==f);
There are three ways in which one might want to compare an int
to a float
. One might want to know:
- Does the closest possible
float
value to theint
match thefloat
? - Does the whole-number part of the
float
match theint
? - Do the
int
andfloat
represent the same numerical value.
If one tries to compare an int
and float
directly, the compiled code will answer the first question; whether that's what the programmer intended, however, will be far from obvious. Changing the comparison to (float)i == f
would make it clear that the first meaning was intended, or (double)i == (double)f
would cause the code to answer the third question (and make it clear that's what was intended).
(*) Even if the C# spec regards a value of type e.g. System.Int32
as being an object of type System.Int32
, such a view is contradicted by the requirement that a code run on a platform whose spec regards values and objects as inhabiting different universes. Further, if T
is a reference type, and x
is a T
, then a reference of type T
should be able to refer to x
. Thus, if a variable v
of type Int32
holds an Object
, a reference of type Object
should be able to hold a reference to v
or its contents. In fact, a reference of type Object
would be able to point to an object holding data copied from v
, but not to v
itself nor to its contents. That would suggest that neither v
nor its contents is really an Object
.
Equals() is a method of System.Object Class
Syntax : Public virtual bool Equals()
Recommendation if we want to compare state of two objects then we should use Equals() method
as stated above answers == operators compare the values are same.
Please don't get confused with ReferenceEqual
Reference Equals()
Syntax : public static bool ReferenceEquals()
It determine whether the specified objects instance are of the same instance
What you need to realize is that doing ==
will always end up calling a method. The question is whether calling ==
and Equals
ends up calling/doing the same things.
With reference types, ==
will always 1st check whether the references are the same (Object.ReferenceEquals
). Equals
on the other hand can be overridden and may check whether some values are equal.
EDIT: to answer svick and add on SLaks comment, here is some IL code
int i1 = 0x22; // ldc.i4.s ie pushes an int32 on the stack
int i2 = 0x33; // ldc.i4.s
short s1 = 0x11; // ldc.i4.s (same as for int32)
short s2 = 0x22; // ldc.i4.s
s1 == i1 // ceq
i1 == s1 // ceq
i1 == i2 // ceq
s1 == s2 // ceq
// no difference between int and short for those 4 cases,
// anyway the shorts are pushed as integers.
i1.Equals(i2) // calls System.Int32.Equals
s1.Equals(s2) // calls System.Int16.Equals
i1.Equals(s1) // calls System.Int32.Equals: s1 is considered as an integer
// - again it was pushed as such on the stack)
s1.Equals(i1) // boxes the int32 then calls System.Int16.Equals
// - int16 has 2 Equals methods: one for in16 and one for Object.
// Casting an int32 into an int16 is not safe, so the Object overload
// must be used instead.
== In Primitive
Console.WriteLine(age == newAge); // true
In primitive comparison == operator behave quite obvious, In C# there are many == operator overload available.
- string == string
- int == int
- uint == uint
- long == long
- many more
So in this case there is no implicit conversion from int
to short
but short
to int
is possible. So newAge is converted into int and comparison occurs which returns true as both holds same value. So it is equivalent to:
Console.WriteLine(age == (int)newAge); // true
.Equals() in Primitive
Console.WriteLine(newAge.Equals(age)); //false
Here we need to see what Equals() method is, we calling Equals with a short type variable. So there are three possibilities:
- Equals(object, object) // static method from object
- Equals(object) // virtual method from object
- Equals(short) // Implements IEquatable.Equals(short)
First type is not case here as number of arguments are different we calling with only one argument of type int. Third is also eliminated as mentioned above implicit conversion of int to short is not possible. So here Second type of Equals(object)
is called. The short.Equals(object)
is:
bool Equals(object z)
{
return z is short && (short)z == this;
}
So here condition got tested z is short
which is false as z is an int so it returns false.
'Programming' 카테고리의 다른 글
통계 분석 및 보고서 작성을위한 워크 플로우 (0) | 2020.05.19 |
---|---|
항목이 배열 / 목록에 있는지 확인 (0) | 2020.05.19 |
/ proc / self / exe없이 현재 실행 파일 경로 찾기 (0) | 2020.05.19 |
.NET에서 사용한 후 개체를 Null / Nothing으로 설정 (0) | 2020.05.18 |
자식 요소에 따라 요소에 CSS 스타일 적용 (0) | 2020.05.18 |