Eu quero usar um Track-Bar
para mudar a Form
opacidade de um.
Este é o meu código:
decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;
Quando crio o aplicativo, ele fornece o seguinte erro:
Não é possível converter implicitamente o tipo
decimal
paradouble
Eu tentei usar trans
e, em double
seguida, o Control
não funciona. Esse código funcionou bem em um projeto anterior do VB.NET.
c#
floating-point
type-conversion
double
decimal
Eggs McLaren
fonte
fonte
Respostas:
Um elenco explícito para
double
isso não é necessário:Identificar a constante como
5000.0
(ou como5000d
) é suficiente:fonte
Uma resposta mais genérica para a pergunta genérica "Decimal versus duplo?": Decimal para cálculos monetários para preservar a precisão, dobro para cálculos científicos que não são afetados por pequenas diferenças. Como Double é um tipo nativo da CPU (a representação interna é armazenada na base 2 ), os cálculos feitos com o Double têm melhor desempenho que o Decimal (representado na base 10 internamente).
fonte
Seu código funcionou bem no VB.NET porque faz implicitamente qualquer conversão, enquanto o C # tem implícitos e explícitos.
Em C #, a conversão de decimal para duplo é explícita à medida que você perde a precisão. Por exemplo, o 1.1 não pode ser expresso com precisão como um duplo, mas como um decimal (consulte " Números de ponto flutuante - mais imprecisos do que você pensa " pelo motivo).
No VB, a conversão foi adicionada para você pelo compilador:
Isso
(double)
precisa ser explicitamente declarado em C #, mas pode ser implícito no compilador mais 'perdoador' do VB.fonte
Por que você está dividindo por 5000? Basta definir os valores Mínimo e Máximo do TrackBar entre 0 e 100 e depois dividir o Valor por 100 para a porcentagem de Opacidade. O exemplo mínimo de 20 abaixo impede que o formulário fique completamente invisível:
fonte
5000
, o OP teria um problema com100
?Você tem dois problemas. Primeiro,
Opacity
requer um valor duplo, não decimal. O compilador está lhe dizendo que, embora haja uma conversão entre decimal e dupla, é uma conversão explícita que você precisa especificar para que funcione. A segunda é queTrackBar.Value
é um valor inteiro e a divisão de um int por um int resulta em um int, independentemente do tipo de variável que você atribui a ele. Nesse caso, há uma conversão implícita de int para decimal ou dupla - porque não há perda de precisão quando você faz a conversão -, portanto, o compilador não reclama, mas o valor que você obtém é sempre 0, presumivelmente, poistrackBar.Value
sempre é menor que 5000. A solução é alterar seu código para usar double (o tipo nativo do Opacity) e fazer aritmética de ponto flutuante, tornando explicitamente a constante um double - o que terá o efeito de promover a aritmética - ou convertertrackBar.Value
para double , que fará a mesma coisa - ou ambos. Ah, e você não precisa da variável intermediária, a menos que seja usada em outro lugar. Meu palpite é que o compilador o otimizaria, de qualquer maneira.fonte
Na minha opinião, é desejável ser o mais explícito possível. Isso adiciona clareza ao código e ajuda seus colegas programadores que eventualmente o leem.
Além de (ou em vez de) anexar
.0
a ao número, você pode usardecimal.ToDouble()
.aqui estão alguns exemplos:
fonte
Parece
this.Opacity
um valor duplo, e o compilador não gosta de você tentar inserir um valor decimal nele.fonte
A propriedade Opacity é do tipo duplo:
ou simplesmente:
ou:
Observe que estou usando
5000.0
(ou5000d
) para forçar uma divisão dupla porquetrackBar1.Value
é um número inteiro e ele executaria uma divisão inteira e o resultado seria um número inteiro.fonte
Você deve usar em
5000.0
vez de5000
.fonte
Supondo que você esteja usando o WinForms,
Form.Opacity
é do tipodouble
, portanto, você deve usar:A menos que você precise do valor em outro lugar, é mais fácil escrever:
A razão pela qual o controle não funciona quando você alterou seu código para simplesmente ser um duplo foi porque você tinha:
que interpretou
5000
como um número inteiro e, comotrackbar1.Value
também é um número inteiro, seutrans
valor sempre foi zero. Tornando explicitamente o valor numérico de ponto flutuante, adicionando.0
o compilador, agora é possível interpretá-lo como um duplo e executar o cálculo adequado.fonte
A melhor solução é:
fonte
Como
Opacity
é um valor duplo, eu usaria apenas um dobro desde o início e não o lançaria, mas certifique-se de usar um dobro ao dividir para não perder precisãofonte
fonte