문제

트랙바를 사용하여 양식의 불투명도를 변경하고 싶습니다.

이것은 내 코드입니다.

decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;

애플리케이션을 빌드할 때 다음 오류가 발생합니다.

유형을 암시적으로 변환할 수 없습니다. 'decimal' 에게 'double'.

나는 사용해 보았다. trans 그리고 double 하지만 컨트롤이 작동하지 않습니다.이 코드는 이전 VB.NET 프로젝트에서 제대로 작동했습니다.

도움이 되었습니까?

해결책

다음과 같이 double로 명시적으로 캐스트할 필요는 없습니다.

double trans = (double) trackBar1.Value / 5000.0;

상수를 다음과 같이 식별합니다. 5000.0 (또는 다음과 같이 5000d) 충분하다:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;

다른 팁

일반적인 질문 "Decimal vs Double?"에 대한 보다 일반적인 답변은 다음과 같습니다. 소수 금전적 계산의 정확성을 유지하기 위해 더블 작은 차이에도 영향을 받지 않는 과학적인 계산을 위해Double은 CPU 고유의 유형이므로(내부 표현은 베이스 2), Double을 사용한 계산은 Decimal(다음으로 표시됨)보다 더 나은 성능을 발휘합니다. 기본 10 내부적으로).

귀하의 코드는 암시적으로 모든 캐스트를 수행하는 반면 C#에는 암시적 및 명시적 캐스트가 모두 있기 때문에 VB.NET에서는 제대로 작동했습니다.

C#에서는 정확성이 떨어지기 때문에 10진수에서 이중으로의 변환이 명시적입니다.예를 들어 1.1은 실수로 정확하게 표현될 수 없지만 십진수로 표현될 수 있습니다("부동 소수점 숫자 - 생각보다 부정확함"라는 이유로).

VB에서는 컴파일러가 변환을 추가했습니다.

decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;

저것 (double) C#에서는 명시적으로 명시해야 하지만 암시된 VB의 보다 '관용적인' 컴파일러입니다.

왜 5000으로 나누나요?TrackBar의 최소값과 최대값을 0에서 100 사이로 설정한 다음 불투명도 비율에 대해 값을 100으로 나눕니다.아래의 최소 20개 예는 양식이 완전히 보이지 않게 되는 것을 방지합니다.

private void Form1_Load(object sender, System.EventArgs e)
{
    TrackBar1.Minimum = 20;
    TrackBar1.Maximum = 100;

    TrackBar1.LargeChange = 10;
    TrackBar1.SmallChange = 1;
    TrackBar1.TickFrequency = 5;
}

private void TrackBar1_Scroll(object sender, System.EventArgs e)
{
    this.Opacity = TrackBar1.Value / 100;
}

두 가지 문제가 있습니다.첫 번째, Opacity 10진수 값이 아닌 double 값이 필요합니다.컴파일러는 10진수와 더블 사이의 변환이 있지만 이것이 작동하려면 지정해야 하는 명시적인 변환임을 알려줍니다.두 번째는 TrackBar.Value 은 정수 값이며 int를 int로 나누면 어떤 유형의 변수에 할당하든 상관없이 int가 됩니다.이 경우 int에서 10진수 또는 double로의 암시적 캐스트가 있습니다. 캐스트를 수행할 때 정밀도 손실이 없기 때문입니다. 따라서 컴파일러는 불평하지 않지만, 얻는 값은 아마도 항상 0입니다. trackBar.Value 항상 5000보다 작습니다.해결책은 double(불투명도의 기본 유형)을 사용하도록 코드를 변경하고 상수를 명시적으로 double(산술을 촉진하는 효과가 있음)로 만들거나 캐스팅하여 부동 소수점 연산을 수행하는 것입니다. trackBar.Value 두 배로 하면 같은 일을 하거나 둘 다 할 수 있습니다.아, 그리고 다른 곳에서 사용하지 않는 한 중간 변수는 필요하지 않습니다.내 생각에는 어쨌든 컴파일러가 그것을 최적화할 것입니다.

trackBar.Opacity = (double)trackBar.Value / 5000.0;

제 생각에는 최대한 명시적인 것이 바람직하다고 생각합니다.이는 코드에 명확성을 더하고 결국 코드를 ​​읽을 동료 프로그래머에게 도움이 됩니다.

추가하는 것 외에도 (또는 대신) .0 번호에 맞게 사용할 수 있습니다. decimal.ToDouble().

여기 몇 가지 예가 있어요.

// Example 1
double transperancy = trackBar1.Value/5000;
this.Opacity = decimal.ToDouble(transperancy);

// Example 2 - with inline temp
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);

처럼 들린다 this.Opacity 는 double 값이고 컴파일러는 여기에 10진수 값을 집어넣는 것을 좋아하지 않습니다.

당신은 사용해야합니다 5000.0 대신에 5000.

그만큼 불투명 속성은 이중 유형입니다.

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

또는 간단하게:

this.Opacity = trackBar1.Value / 5000.0;

또는:

this.Opacity = trackBar1.Value / 5000d;

내가 사용하고 있음을 주목하세요 5000.0 (또는 5000d) 이중 나누기를 강제하기 때문에 trackBar1.Value 은 정수이고 정수 나누기를 수행하며 결과는 정수입니다.

WinForms를 사용한다고 가정하면, Form.Opacity 유형이다 double, 이므로 다음을 사용해야 합니다.

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

다른 곳에서 값이 필요하지 않은 한 다음과 같이 작성하는 것이 더 간단합니다.

this.Opacity = trackBar1.Value / 5000.0;

코드를 단순히 double로 변경했을 때 컨트롤이 작동하지 않는 이유는 다음과 같습니다.

double trans = trackbar1.Value / 5000;

해석한 것은 5000 정수로, 그리고 왜냐하면 trackbar1.Value 은 또한 정수입니다. trans 값은 항상 0이었습니다.다음을 추가하여 숫자를 부동 소수점 값으로 명시적으로 만듭니다. .0 이제 컴파일러는 이를 double로 해석하고 적절한 계산을 수행할 수 있습니다.

가장 좋은 해결책은 다음과 같습니다.

this.Opacity = decimal.ToDouble(trackBar1.Value/5000);

부터 Opacity 는 double 값입니다. 처음부터 double을 사용하고 전혀 캐스트하지 않겠습니다. 하지만 나눌 때는 정밀도를 잃지 않도록 double을 사용해야 합니다.

Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top