캐스팅과 Convert.To () 메서드 사용의 차이점


88

나는 캐스트 기능이 doublestring값을.

string variable = "5.00"; 

double varDouble = (double)variable;

코드 변경이 체크인되었으며 프로젝트가 오류와 함께 빌드됩니다. System.InvalidCastException: Specified cast is not valid.

그러나 다음을 수행하면 ...

string variable = "5.00"; 

double varDouble = Convert.ToDouble(variable);

... 프로젝트는 오류없이 빌드됩니다.

캐스팅과 Convert.To()방법 사용의 차이점은 무엇입니까 ?캐스팅은 왜 던지고 Exception사용 Convert.To()하지 않습니까?

c#  casting 


6
에 관해서 언급 질문 , 영업 이익은 주조 또는 변환하고, 사용할 때 요청 허용 응답 상태를, "그것은 당신이 사용 중 선택의 문제가 정말." 나는 캐스트와 개종자의 차이를 요구하고 있습니다. 내 의견으로는 아래 답변 (kudos SO!)이 "이것 또는 저것을 선택하여 사용"하는 것과 비교하여 더 자세한 정보를 제공하며,이 세부 사항은 본질적으로 더 많은 정보에 입각 한 선택을하는 데 사용될 수 있습니다.

@ edmastermind29 프로그래밍 컨텍스트에서 "x와 y의 차이는 무엇입니까"와 "x와 y를 사용할시기"사이에는 큰 차이가 없습니다. 둘 다 서로에게 서로 대답합니다.
nawfal 2013

2
거의 3 년이 지난 지금이 ​​경우에는 서로가 서로 대답하지 않는 것 같습니다. Q : "X와 Y의 차이점은 무엇입니까?" A : "어떤 것을 사용하든 정말 선택의 문제입니다." 별로 유용하지 않습니다.

누구도 최고의 성능이 질문의 일부인 직접적인 대답을 갖고 있지 않은 것 같습니다. 내 경험상 Cast가 특히 이와 같은 열 값을 얻는 데 더 낫다는 것을 알 수 있습니다. (int) datatable.Rows [0] [0], if 우리는 100 % INT 알
Sundara Prabu에게

답변:


126

어떻게 든 동등하다고 볼 있더라도 목적이 완전히 다릅니다. 먼저 캐스트가 무엇인지 정의 해 보겠습니다.

캐스팅은 한 데이터 유형의 엔티티를 다른 유형으로 변경하는 작업입니다.

캐스트는 종종 동일한 변환 구문을 갖기 때문에 약간 일반적이며 변환 과 동일합니다. 그러므로 질문은 언어에서 캐스트 (암시 적 또는 명시 적)를 허용 할 때와 언제 ( 더) 명시 적 변환?

먼저 그들 사이에 간단한 선을 그리 겠습니다 . 형식적으로 (언어 구문과 동일하더라도) 캐스트는 유형을 변경하는 반면 변환은 값을 변경하거나 변경할 수 있습니다 (결국 함께 유형 함께). 또한 캐스트는 되돌릴 수 있지만 변환은 불가능할 수 있습니다.

이 주제는 상당히 방대하므로 게임에서 커스텀 캐스트 연산자를 제외하여 조금 좁혀 보겠습니다.

암시 적 캐스트

C #에서는 정보를 잃지 않을 때 캐스트가 암시 적 입니다 (이 검사는 실제 값이 아닌 형식 으로 수행 됩니다. ).

기본 유형

예를 들면 :

int tinyInteger = 10;
long bigInteger = tinyInteger;

float tinyReal = 10.0f;
double bigReal = tinyReal;

이러한 캐스트는 변환하는 동안 정보를 잃지 않을 것이기 때문에 암시 적입니다 (유형을 더 넓게 만들기 만하면 됨). 그 반대의 경우 암시 적 캐스트는 허용되지 않습니다. 실제 값에 관계없이 (런타임에서만 확인할 수 있기 때문에) 변환 중에 일부 정보가 손실 될 수 있기 때문입니다. 예를 들어이 코드는 다음 double과 같이 표현할 수없는 값을 포함 할 수 있기 때문에 컴파일 되지 않습니다 float.

// won't compile!
double bigReal = Double.MaxValue;
float tinyReal = bigReal;

사물

객체 (에 대한 포인터)의 경우 컴파일러가 소스 유형이 파생 클래스 (또는 대상 클래스의 유형을 구현)인지 확인할 수있을 때 캐스트는 항상 암시 적입니다. 예를 들면 다음과 같습니다.

string text = "123";
IFormattable formattable = text;

NotSupportedException derivedException = new NotSupportedException();
Exception baseException = derivedException;

이 경우 컴파일러는 알고string구현을 IFormattable하고는 NotSupportedException(에서 파생)입니다 Exception캐스트가 암시하므로. 객체가 유형을 변경하지 않기 때문에 정보가 손실되지 않습니다 ( struct캐스트를 사용하면 다른 유형새 객체 를 생성하기 때문에 s 및 기본 유형과 다릅니다 ). 가 변경됩니다. 그들.

명시 적 캐스트

변환이 컴파일러에 의해 암시 적으로 수행되지 않은 경우 캐스트는 명시 적이며 캐스트 연산자를 사용해야합니다. 일반적으로 다음을 의미합니다.

  • 정보 나 데이터를 잃을 수 있으므로 알고 있어야합니다.
  • 변환이 실패 할 수 있습니다 (한 유형을 다른 유형으로 변환 할 수 없기 때문에). 따라서 수행중인 작업을 알고 있어야합니다.

기본 유형

변환 중에 일부 데이터가 손실 될 수있는 경우 기본 유형에 대해 명시 적 캐스트가 필요합니다. 예를 들면 다음과 같습니다.

double precise = Math.Cos(Math.PI * 1.23456) / Math.Sin(1.23456);
float coarse = (float)precise;

float epsilon = (float)Double.Epsilon;

두 예에서 값이 float범위 내에 있더라도 정보 (이 경우 정밀도)가 손실되므로 변환이 명시 적이어야합니다. 이제 이것을 시도하십시오.

float max = (float)Double.MaxValue;

이 변환은 실패하므로 다시 명시 적이어야하며이를인지하고 확인을 수행 할 수 있습니다 (이 예에서는 값이 일정하지만 일부 런타임 계산 또는 I / O에서 올 수 있음). 귀하의 예로 돌아가십시오.

// won't compile!
string text = "123";
double value = (double)text;

컴파일러가 텍스트를 숫자로 변환 할 수 없기 때문에 컴파일되지 않습니다. 텍스트에는 숫자뿐만 아니라 모든 문자가 포함될 수 있으며 C #에서는 명시 적 캐스트의 경우에도 너무 많습니다 (하지만 다른 언어에서는 허용 될 수 있음).

사물

유형이 관련되지 않은 경우 포인터에서 객체로의 변환이 실패 할 수 있습니다. 예를 들어이 코드는 컴파일되지 않습니다 (컴파일러가 가능한 변환이 없음을 알고 있기 때문).

// won't compile!    
string text = (string)AppDomain.Current;
Exception exception = (Exception)"abc";

이 코드는 컴파일되지만 런타임에 실패 할 수 있습니다 (캐스트 된 객체의 유효 유형에 따라 다름) InvalidCastException.

object obj = GetNextObjectFromInput();
string text = (string)obj;

obj = GetNextObjectFromInput();
Exception exception = (Exception)obj;

전환

그래서 마지막으로 캐스트가 변환이라면 왜 우리는 같은 클래스가 필요 Convert합니까? 실제로 Convert구현 및 IConvertible구현 에서 발생하는 미묘한 차이점을 무시하는 것은 C #에서 캐스트를 사용하여 컴파일러에 말하기 때문입니다.

저를 믿으세요.이 타입은 지금은 알 수 없더라도 저런 타입입니다.

-또는-

걱정하지 마세요.이 전환에서 무언가가 손실 되더라도 상관 없습니다.

다른 어떤 경우에는 보다 명시적인 작업이 필요합니다 ( 쉬운 캐스트의 의미에 대해 생각해보십시오. 이것이 C ++에서 길고 장황하며 명시적인 구문을 도입 한 이유입니다). 이것은 복잡한 작업을 포함 할 수 있습니다 ( string-> double변환을 위해 구문 분석이 필요합니다). string예를 들어으로 변환하는 것은 항상 가능합니다 ( ToString()메소드 를 통해 ).하지만 예상과 다른 것을 의미 할 수 있으므로 캐스트보다 더 명시 적이어야합니다 ( 더 많이 작성하고 수행중인 작업에 대해 더 많이 생각합니다. ).

이 변환은 사용자 지정 변환 연산자 (캐스트 할 클래스에 정의 됨) 또는 더 복잡한 메커니즘 ( TypeConverter예 : s 또는 클래스 메서드 )을 사용하여 객체 내에서 수행 할 수 있습니다 (알려진 IL 명령어 사용 ). 어떤 일이 일어날 지 모르지만 실패 할 수 있다는 것을 알고 있습니다 (더 제어 된 변환이 가능할 때 IMO 를 사용해야하는 이유입니다). 귀하의 경우 변환은 단순히을 구문 분석하여 다음 string을 생성합니다 double.

double value = Double.Parse(aStringVariable);

물론 이것은 실패 할 수 있으므로이를 수행하면 항상 예외가 발생할 수 있습니다 ( FormatException). 그것은 여기에 주제에 밖으로이다 그러나이 때 TryParse사용할 수 있습니다 의미 당신이 때문에 당신은 (그것을 사용한다 라고 는 숫자하지 않을 수 있습니다 그것은 실패 ...도 빠릅니다).

.NET의 변환은 TypeConverter사용자 정의 변환 연산자를 사용한 암시 적 / 명시 적 캐스트,IConvertible 메서드 및 구문 분석 (내가 잊은 것이 있습니까?) . 이에 대한 자세한 내용은 MSDN을 참조하십시오.

이 긴 대답을 끝내려면 사용자 정의 변환 연산자에 대해 몇 마디 만하면됩니다. 그것은 단지 설탕 프로그래머가 다른 한 가지 유형으로 캐스팅을 사용하게 할 수 있습니다. "이 유형을 해당 유형으로 변환하려면 내가 할 수 있습니다"라고 말하는 클래스 (캐스트 될 것) 내부의 메소드입니다. 예를 들면 :

float? maybe = 10; // Equals to Nullable<float> maybe = 10;
float sure1 = (float)maybe; // With cast
float sure2 = maybe.Value; // Without cast

이 경우 실패 할 수 있기 때문에 명시 적이지만 구현에 맡겨집니다 (이에 대한 지침이 있더라도). 다음과 같은 사용자 지정 문자열 클래스를 작성한다고 가정 해보십시오.

EasyString text = "123"; // Implicit from string
double value = (string)text; // Explicit to double

구현에서 "프로그래머의 삶을 더 쉽게 만들기"를 결정하고 캐스트를 통해이 변환을 노출 할 수 있습니다 (단순히 작성하는 지름길 일뿐임을 기억하십시오). 일부 언어는이를 허용 할 수도 있습니다.

double value = "123";

모든 유형에 대한 암시 적 변환 허용 (확인은 런타임에 수행됨). 적절한 옵션을 사용하면 예를 들어 VB.NET에서이를 수행 할 수 있습니다. 그것은 단지 다른 철학입니다.

그들로 무엇을 할 수 있습니까?

그래서 마지막 질문은 언제 하나 또는 다른 것을 사용해야 하는가입니다. 언제 명시 적 캐스트를 사용할 수 있는지 살펴 보겠습니다.

  • 기본 유형 간의 변환.
  • 전환 object 다른 유형으로의 (개봉도 포함될 수 있음).
  • 파생 클래스에서 기본 클래스 (또는 구현 된 인터페이스) 로의 변환.
  • 사용자 지정 변환 연산자를 통해 한 유형에서 다른 유형으로 변환합니다.

첫 번째 변환 만 수행 할 수 있습니다. Convert 선택의 여지가없고 명시 적 캐스트를 사용해야합니다.

이제 언제 사용할 수 있는지 보겠습니다 Convert.

  • 모든 기본 유형에서 다른 기본 유형으로의 변환 (몇 가지 제한 사항이 있음, MSDN 참조 ).
  • IConvertible다른 (지원되는) 유형으로 구현되는 모든 유형에서 변환 .
  • byte배열에서 문자열로 /에서 변환 .

결론

Convert변환이 실패 할 수 있다는 것을 알 때마다 IMO를 사용해야합니다 (형식, 범위 또는 지원되지 않을 수 있기 때문). 캐스트로 동일한 변환을 수행 할 수 있더라도 (다른 것을 사용할 수없는 경우). 누가 여러분의 코드를 읽을 것인지 명확하게 , 그리고 그것이 실패 할 수 있다는 것을 분명히합니다 (디버그 단순화).

캐스트를 사용해야하는 다른 모든 경우에는 선택의 여지가 없지만 다른 더 나은 방법을 사용할 수 있으면 사용하는 것이 좋습니다. 당신의 예에서의 변환 string에는 double가능한 한 (또한 당신이 그것을보다 효율적으로 제어를 얻을 수) 명시 적으로 많이 그것을해야하므로 매우 자주 사용 예를 들어, 실패합니다 (텍스트가 사용자로부터 온다 특히)하는 것이 뭔가 TryParse방법을.

편집 : 그들 사이의 차이점은 무엇입니까?

(대한 업데이트 된 질문에 따라 그리고 내가 전에 쓴 유지 하면 당신은 / 사용 할 수 있습니다 때에 비해 캐스트를 사용할 수 있습니다 Convert또한 (그들 사이의 차이가있는 경우입니다 명확히 다음 마지막 점) Convert용도 IConvertibleIFormattable인터페이스가 작업을 수행 할 수 있도록 캐스트와 함께 허용되지 않음).

짧은 대답은 그렇습니다. 그들은 다르게 행동합니다 . 나는 Convert클래스가 도우미 메서드 클래스처럼 보이지만 종종 약간의 이점 이나 약간 다른 동작을 제공합니다. 예를 들면 :

double real = 1.6;
int castedInteger = (int)real; // 1
int convertedInteger = Convert.ToInt32(real); // 2

꽤 다르죠? 캐스트는 잘리지 만 (우리 모두가 기대하는 것입니다) Convert가장 가까운 정수로 반올림을 수행합니다 (알지 못하는 경우 예상되지 않을 수 있음). 각 변환 방법에는 차이가 있으므로 일반적인 규칙을 적용 할 수 없으며 사례별로 확인해야합니다 ... 19 가지 기본 유형을 다른 모든 유형으로 변환 할 수 있습니다 ... 목록은 꽤 길 수 있습니다. MSDN 사례를 참조하는 것이 훨씬 좋습니다. 케이스!


질문을 변경했습니다 Difference between casting and using the Convert.To() method. 그렇지 않으면 매우 포괄적 인 답변입니다. (나는 ... 내 질문이 재개되기를 기대)

@ edmastermind29 나는 질문을 조금 수정했는데, 긴 답변에도 주제가 너무 깁니다 (목록에 대한 300 개 이상의 변환 가능). Convert는 캐스트뿐만 아니라 "일반"IConvertible 및 IFormattable 인터페이스에 대해서도 이점 (또는 예상치 못한 동작?)을 추가합니다.
Adriano Repetti 2013 년

double정수를 나타내지 않는 값은 "변환 가능"해야한다는 C에서 빌린 개념이 마음에 들지 않습니다 int. 캐스트는 예를 들어 하나가 검색되는 경우에 적절한 패러다임 것 같다 Int32A로부터 값을 double[]실제 숫자와의 혼합 보유하고 Int32변환 된 값을 double표현할 수없는 값을 변환 [시도 정확하게int32예기치 않은 상태를 나타냅니다를 예외를 발생시켜야합니다]하지만 손실 변환을 원할 때 원하는 형식에 대해 구체적이어야한다고 생각합니다.
supercat

1
또 다른 차이점은 객체에서 기본 유형으로입니다. 예object o = 123; var l = Convert.ToInt64(o); var i = (long) (int) o; var f = (long) o // InvalidCastException
yue shi

1
@ rory.ap은 중요한 포인트입니다. 아니요, 공식적으로 캐스트 ( float-> int)가 아니라 강제 입니다. 캐스트는 예를 들어 DerivedClass-> 일 수 있습니다 BaseClass. C #에서는 두 가지 모두에 대해 동일한 단어 (및 연산자)를 사용하지만 실제로는 별개이기 때문에 혼란 스럽습니다. 그것들을 구별하는 공식적인 정의는 내가 쓴 것보다 약간 더 복잡합니다.
Adriano Repetti

12

캐스팅은 컴파일러에게 "이 변수가 Bar라고 생각하는 것을 알고 있지만, 나는 당신보다 더 많이 알고 있습니다. 객체는 실제로 Foo입니다. 지금." 그런 다음 런타임에 실제 객체가 실제로 Foo로 판명되면 코드가 작동하고 객체가 Foo가 아님이 밝혀지면 예외가 발생합니다. (특히 System.InvalidCastException.)

반면에 변환은 "Bar 유형의 객체를 주면 해당 Bar 객체에있는 것을 나타내는 새로운 Foo 객체를 만들 수 있습니다. 원래 객체를 변경하지 않을 것입니다."라고 말하는 방법입니다. t 원래 객체를 다르게 취급하면 다른 가치에 기반한 새로운 무언가만들어 낼 수 있습니다.Convert.ToDouble 는 호출 끝날 것Double.Parse어떤 유형의 문자열이 어떤 숫자 값을 나타내는 지 결정하기위한 모든 종류의 복잡한 논리가 있습니다. 문자열을 다르게 double로 매핑하는 자체 변환 방법을 작성할 수 있습니다 (아마도 로마 숫자 등과 같은 숫자 표시에 대해 완전히 다른 규칙을 지원하기 위해). 변환은 무엇이든 할 수 있지만, 아이디어는 컴파일러에게 당신을 위해 아무것도하도록 요청하는 것이 아니라는 것입니다. 여러분의 도움없이 컴파일러는 a를 .NET에 매핑하는 방법을 알 수 없기 때문에 새 객체를 만드는 방법을 결정하는 코드를 작성 string하는 사람 double입니다.

그렇다면 언제 전환하고 언제 캐스팅합니까? 두 경우 모두 어떤 유형의 변수를 가지고 있고, A라고합시다. 그리고 우리는 B 유형의 변수를 원합니다. 우리의 A 객체가 실제로 실제로 B이면 우리는 캐스트합니다. 실제로 B가 아니라면이를 변환하고 프로그램이 A로부터 B를 얻는 방법을 정의해야합니다.


SO 게시물 중 하나에서 Eric Lippert 는 암시 적 캐스트 라는 것은 없으며 암시 적 변환 이라고 언급했습니다 . 나는 캐스트와 변환을 같은 의미로 사용하고 있습니다. "암시 적 캐스트"를 말하는 것이 잘못된 것은 무엇입니까? 변환이 캐스트를 요구하지 않고 암시 적이면 "암시 적 캐스트"라고 말할 수 있습니까?
rahulaga_dev

1
@RahulAgarwal은 무엇 캐스트는 것은 할 당신이 필요로하는 작업입니다 명시 적으로 지정된 유형이 다른 유형의 유효한 인스턴스 (또는으로 할 수있다)을 나타냅니다. 암시 적 변환이 존재 하면 유형을 다른 유형으로 처리하기 위해 캐스트가 필요하지 않습니다 . 따라서 "암시 적 캐스트"라고 말하는 것은 실제로 의미가 없습니다 (Eric과 같이 개발자가 캐스트 연산자를 입력하지 않고 캐스트 연산자를 추가하는 경우 (예 :)를 사용할 때 언급 한 몇 가지 상황을 제외하면 foreach). 이러한 예외 외에 캐스트는 정의상 명시 적입니다.
Servy

5

에서 MSDN:

명시 적 변환 (캐스트) : 명시 적 변환에는 캐스트 연산자가 필요합니다. 변환에서 정보가 손실되거나 다른 이유로 변환이 성공하지 못할 캐스팅이 필요합니다 . 일반적인 예로는 정밀도가 낮거나 범위가 더 작은 형식으로의 숫자 변환과 기본 클래스 인스턴스를 파생 클래스로 변환하는 것이 있습니다.

다음 예를 고려하십시오.

double a = 2548.3;
int b;
b = (int)a; //2548 --> information (.3) lost in the conversion

그리고 또한:

캐스트는 변환을 수행 할 계획이며 데이터 손실이 발생할 수 있음을 알고 있음을 컴파일러에 명시 적으로 알리는 방법입니다.

호환되지 않는 유형 System.Convert간에 변환하려는 경우 클래스를 사용할 수 있습니다. 큰 차이점 사이 주조변환이 있다 컴파일런타임 . 유형 변환 예외는 런타임 에 나타납니다 . 즉, 런타임에 실패한 유형 캐스트 는를 throw합니다. InvalidCastException


결론 : 캐스팅에서 당신은 컴파일러에게 a진짜 타입 b이고 만약 그렇다면 프로젝트는이 예제와 같이 오류없이 빌드 된다는 것을 말하고 있습니다 .

double s = 2;
int a = (int) s;

그러나 변환에서 당신은 컴파일러에게 a유형 의 새 객체를 만드는 방법이 있다고 말하고 있습니다. b제발 그것을하고 프로젝트는 오류없이 빌드하지만 런타임에 유형 캐스트가 실패하면InvalidCastException 말했듯 이 던져진다 .

예를 들어 아래 코드는 컴파일러가 유형의 표현식을 type DateTime으로 캐스팅 할 수 없음을 감지하므로 컴파일되지 않습니다 int.

DateTime s = DateTime.Now;
int a = (int)(s);

그러나 이것은 성공적으로 컴파일되었습니다.

DateTime s = DateTime.Now;
int a = Convert.ToInt32(s);

그러나 런타임에는 다음과 같은 내용이 표시됩니다 InvalidCastException.

'DateTime'에서 'Int32'로의 캐스트가 잘못되었습니다.


4

Convert.Double메서드는 실제로 내부적으로Double.Parse(string) 메서드를 .

어느 String유형이나 Double캐스팅은 항상 실패 때문에 유형은 두 가지 유형 사이의 명시 적 / 암시 적 변환을 정의합니다.

Double.Parse메서드는의 각 문자를 살펴보고의 문자 string값을 기반으로 숫자 값을 string만듭니다. 잘못된 문자가 있으면 Parse메서드가 실패합니다 ( Convert.Double메서드도 실패 함).


1
그리고 이것이 명시 적 캐스트와 어떻게 다른가요?

3
명시 적 캐스트는 데이터 유형이 무엇인지 확인하지 않고 바이트 만 확인합니다. 예를 들어 char x = '1'을 정수로 캐스팅하고 정수는 49가됩니다. 왜냐하면 cahracter '1'이 ascii 테이블에서 # 49이기 때문입니다
user1751547

@ user1751547 그렇다면 사용자가 Convert.ToDouble()바이트를 넘어서 데이터를 고려할까요?

@ user1751547이 질문에 제대로 대답하는 데 필요한 직감이라고 생각합니다. 단순히 "정의되지 않았습니다"라고 말하는 것은 약간의 문제입니다.
Ant P

@ edmastermind29 예, 입력 유형을보고 문자열이면 각 문자를 통과하여 문자의 ascii 값이 49이면 '1'문자이고 올바르게 변환합니다.
user1751547

3

귀하의 예에서 문자열을 double (비 정수 유형)으로 캐스트하려고 시도하고 있습니다.

작동하려면 명시 적 변환이 필요합니다.

그리고 나는 당신이 int로 변환 할 때 double 값의 소수 부분을 잃을 수 있기 때문에 Convert.ToDouble대신 사용할 수 있음을 지적해야합니다 Convert.ToInt64.

변수 값이 "5.25"인 경우 varDouble은 5.00 (Int64 로의 변환으로 인한 0.25 손실)이됩니다.

캐스팅과 변환에 대한 질문에 대답합니다.

캐스트 (명시 적 캐스트)가 명시 적 캐스트의 요구 사항을 충족하지 않습니다. 캐스트 연산자로 캐스트하려는 값이 유효하지 않습니다 (즉, 정수가 아님).

캐스팅 / 변환 규칙을 보려면 이 MSDN 페이지 를 방문하십시오.


@ edmastermind29 내 답변을 업데이트했습니다. 나는 그것이 당신의 질문에 답하기를 바랍니다.
scartag

내 질문과 관련하여 명시 적 캐스트에 대한 요구 사항은 무엇입니까? "비 적분"값과 관련이 있습니까?

@ edmastermind29 네. 숫자 유형으로 캐스트하려는 값이 숫자가 아닌 경우 캐스트가 유효하지 않습니다. 변환이 필요합니다.
scartag

3

캐스팅에는 변환이 포함되지 않습니다. 즉, 값의 내부 표현이 변경되지 않습니다. 예:

object o = "Hello"; // o is typed as object and contains a string.
string s = (string)o; // This works only if o really contains a string or null.

당신은 변환 할 수 있습니다 doublestring 이 좋아

double d = 5;
string s = d.ToString(); // -> "5"

// Or by specifying a format
string formatted = d.ToString("N2"); // -> "5.00"

a string를 a 로 변환 할 수 있습니다 .double여러 가지 방법으로 (여기서는 두 가지 방법).

string s = "5";
double d = Double.Parse(s); // Throws an exception if s does not contain a valid number

또는 안전한 방법

string s = "5";
double d;
if (Double.TryParse(s, out d)) {
    Console.WriteLine("OK. Result = {0}", d);
} else {
    Console.WriteLine("oops!");
}

Convert.ToDouble()내부적으로Double.Parse() . 사용 Convert.ToDouble()하는 것이 유리한 Double.Parse()가요?

Convert.ToDouble다양한 유형의 입력을 허용하는 많은 과부하가 있습니다. 오버로드 수락 string은 문자열이 전달 0.0되면 반환 됩니다 null. 이 외에도 나는 그것을 사용하는 데 아무런 도움이되지 않습니다.
Olivier Jacot-Descombes 2013

그래서, 아니면 ... 또는 Double.Parse()내가 고려해야 할 제안이 있습니까?

Double.Parse()보다 직접적 Convert.ToDouble()입니다. 문자열에 유효한 숫자가 포함되어 있다고 확신하면 안전하게 사용할 수 있습니다 Double.TryParse. 그렇지 않으면를 사용하는 것이 좋습니다 .
Olivier Jacot-Descombes 2013

1
string variable = "5.00";     
double varDouble = (double)variable;

위의 변환은 단순히 언어에 의해 허용되지 않습니다. 다음은 숫자 유형에 대한 명시 적 캐스트 목록입니다. http://msdn.microsoft.com/en-us/library/yht2cx7b.aspx 보시다시피 모든 숫자 유형이 다른 숫자 유형으로 변환 될 수있는 것은 아닙니다.

여기에서 전송에 대한 추가 정보

그리고 이것이 Convert.ToDouble ()과 어떻게 다른가요?

유형을 캐스트 할 때 데이터 구조는 변경되지 않습니다. 음, 숫자 값 변환의 경우 몇 비트를 풀거나 추가 0 비트를 얻을 수 있습니다. 그러나 당신은 여전히 ​​숫자로 작업하고 있습니다. 당신은 그 숫자가 차지하는 메모리 양을 변경하고 있습니다. 컴파일러가 필요한 모든 작업을 수행하기에 충분히 안전합니다.

그러나 문자열을 숫자로 캐스트하려고 할 때 변수가 차지하는 메모리 양을 변경하는 것만으로는 충분하지 않기 때문에 그렇게 할 수 없습니다. 예를 들어 5.00문자열은 "숫자"의 시퀀스입니다. 53 (5) 46 (.) 48 (0) 48 (0)-ASCII 용이지만 문자열에는 비슷한 내용이 포함됩니다. 컴파일러가 문자열에서 처음 N (더블의 경우 4? 확실하지 않음) 바이트를 가져 오면 해당 조각에는 완전히 다른 이중 숫자가 포함됩니다. 동시에 Convert.ToDouble ()은 문자열의 각 기호를 사용하는 특수 알고리즘을 실행하고, 문자열이 숫자를 나타내는 경우 나타내는 숫자를 파악하고 두 배로 만듭니다. PHP와 같은 언어는 대략적으로 말하면 백그라운드에서 Convert.ToDouble을 호출합니다. 그러나 C #은 정적으로 형식화 된 언어처럼이를 수행하지 않습니다. 이를 통해 모든 작업이 형식에 안전하고 다음과 같은 작업을 수행하는 동안 예기치 않은 작업이 발생하지 않도록 할 수 있습니다.

double d = (double)"zzzz"

@ edmastermind29 업데이트 된 답변을 참조하십시오. 나는 그것을 설명하려고 노력했다. 설명은 완벽하지 않지만 차이점을 설명한다고 가정합니다.
Viktor S.

1

문자열을 이중으로 캐스팅하는 것은 허용되지 않습니다. C #은 예외가 발생하는 이유이므로 문자열을 변환해야합니다 ( 허용되는 변환 경로를 보여주는 MSDN 문서 ). 이것은 단순히 문자열이 반드시 숫자 데이터를 포함 할 필요는 없지만 다양한 숫자 유형 (null 값 제외)을 포함하기 때문입니다. A Convert는 문자열을 숫자 값으로 변환 할 수 있는지 확인하는 메서드를 실행합니다. 가능한 경우 해당 값을 반환합니다. 할 수 없으면 예외가 발생합니다.

변환하려면 몇 가지 옵션이 있습니다. 귀하 Convert의 질문 에서 방법을 사용 Parse했는데.와 거의 유사한 방법이 Convert있지만 다음을 수행 할 수 있는 TryParse 도 살펴 봐야합니다 .

string variable = "5.00"; 

double varDouble;

if (Double.TryParse(variable, out varDouble)) {
    //Code that runs if the conversion succeeded.
} else {
    //Code that runs if the conversion failed.
}

이렇게하면 가능한 예외 ConvertParse숫자가 아닌 문자열을 피할 수 있습니다 .


변환이 성공했는지 확인 하기 때문에 TryParse오버 를 사용하는 것이 유리 합니까? ConvertTryParse

@ edmastermind29 그렇게 생각합니다. 변환이 실패하면 Convert에서 예외가 발생합니다. TryParse는 변환이 성공하면 True, 실패하면 False를 반환합니다.
Keen

1

double varDouble = (double)variablevariable이미 이중 이라고 가정합니다 . 경우 variable이중 (이 문자열의)없는 다음이 실패합니다. double varDouble = Convert.ToDouble(variable)그것이 말하는 것처럼-그것은 변환합니다. 파싱하거나 다른 방식으로 double을 추출 할 수 있다면 그렇게 될 variable것입니다.

나는 두 번째로 Double.Parse또는 Double.TryParse어떤 일이 일어나야하는지 더 명확하게 나타 내기 때문에 사용 합니다. 문자열로 시작하여 double로 변환 할 수있을 것으로 예상합니다. 의심스러운 점이 있으면 TryParse.

경우 variable메소드 인수가, 두 배로 유형을 변경합니다. 발신자에게 올바른 유형을 제공해야합니다. 그런 식으로 컴파일러가 작업을 수행합니다.


-1

가장 중요한 차이점은 타입 캐스팅 이 사용되고 변환이 실패하면 (예를 들어 매우 큰 float 값을 int로 변환하는 경우) 예외가 발생하지 않고 int가 보유 할 수있는 최소값이 표시된다는 것입니다. 그러나 Convert 를 사용 하는 경우 이러한 시나리오에서는 예외가 발생합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.