Pertanyaan Cara elegan untuk meniadakan nilai numerik berdasarkan nilai boolean


Saya memiliki variabel desimal yang ingin saya tolak jika variabel boolean benar. Adakah yang bisa memikirkan cara yang lebih elegan untuk melakukannya selain ini:

decimal amount = 500m;
bool negate = true;

amount *= (negate ? -1 : 1);

Saya memikirkan sesuatu di sepanjang garis operator bitwise atau implementasi matematika yang ketat.


4
2017-08-01 17:29


asal


Jawaban:


Secara pribadi, saya hanya akan menggunakan pernyataan if, karena saya merasa bahwa ini adalah yang paling jelas dalam hal maksud:

decimal amount = 500m;
bool negate = true;

// ...

if (negate)
    amount *= -1;

Ini benar-benar tidak ada pengetikan tambahan (sebenarnya lebih pendek!), Dan lebih jelas menurut saya.


13
2017-08-01 17:32



Gunakan operator negosiator desimal desimal (seperti yang sudah Anda lakukan):

using System;

class Program
{
    static void Main()
    {
        bool negate = true;
        decimal test = 500M;
        Console.WriteLine(negate == true ? -test : test);
    }
}

Keluaran:

-500

Terus terang, ini jauh lebih jelas dan lebih baik daripada mengalikan dengan -1 dengan cara yang aneh.


2
2017-08-01 17:59



Tembakan lain melintasi penyihir matematika?

Bagaimana jika menyesuaikan solusi yang ada agar sedikit lebih mudah dibaca, tetapi tetap menggunakan pernyataan itu? Benar: cara pintas palsu?

Solusi Anda adalah:

amount *= (negate ? -1 : 1);

Mungkin refactor itu

amount = (negate ? amount*-1 : amount);

Untuk menambahkan lebih banyak keterbacaan ke kode Anda, Anda dapat membuat kelas yang dapat digunakan kembali yang menangani hal semacam itu untuk Anda:

public static class MathHelpers()
{
  // Negates the result if shouldNegate is true, otherwise returns the same result
  public static decimal Negate(decimal value, bool shouldNegate)
  {
    // In this black-box solution you can use "fancier" shortcuts
    return value *= negate ? -1 : 1;
  }
}

Dan di kode Anda yang lain, Anda kini memiliki fungsi yang sangat mudah dibaca untuk digunakan ...

decimal amount = 500m;
bool negate = true;
amount = MathHelper.Negate(amount, negate);

Semua dalam semua, meskipun saya setuju bahwa keanggunan dan keterbacaan hidup di gerobak yang sama, tidak berbeda:

if (condition)
  output *= -1;

lebih mudah dibaca daripada

value *= condition ? -1 : 1;

2
2017-08-01 19:09



public static decimal Negate(this decimal value, bool isNegate){
    if(isNegate) return value * -1;
    return value;
}

Buat metode penyuluhan pada desimal. Mudah digunakan.

sebut seperti amount.Negate(negate)


1
2017-08-01 17:37



Ini sudah ada, sejak Kerangka 1.1:

Metode System.Decimal.Negate

desimal statis publik Negate (     desimal d )

Penggunaan Sampel:

decimal amount = 500m;
bool negate = true;

if(negate)
    amount = decimal.Negate(amount);
// amount now holds -500
// Use amount

1
2017-08-02 18:43



Jika Anda negate bendera didasarkan pada beberapa nilai numerik yang dapat Anda gunakan Math.Sign, itulah cara paling "matematis" yang bisa saya pikirkan.

double negationValue = -45.0;
amount *= Math.Sign(negationValue);

atau dalam kasus boolean saja (tidak benar-benar elegan):

amount *= Math.Sign(0.5 - Convert.ToByte(negate));

0
2017-08-01 17:37



amount *= Math.Pow(-1, Convert.ToInt32(negate))

Ini adalah asumsi bahwa typecasting boolean di C # akan menghasilkan 0 pada false, dan 1 untuk true. Namun saya tidak berpikir ini elegan karena merupakan kebingungan.

edit: dikonversi ke int


-1
2017-08-01 17:40