C # 'daki yanlış operatör ne işe yarar?


107

C # 'da iki garip operatör var:

Bu hakkı anlarsam, bu operatörler bir boole ifadesi yerine kullanmak istediğim ve bool'a örtük bir dönüşüm sağlamak istemediğim türlerde kullanılabilir.

Diyelim ki aşağıdaki bir sınıfım var:

    public class MyType
    {
        public readonly int Value;

        public MyType(int value)
        {
            Value = value;
        }

        public static bool operator true (MyType mt)
        {
            return  mt.Value > 0;
        }

        public static bool operator false (MyType mt)
        {
            return  mt.Value < 0;
        }

    }

Böylece şu kodu yazabilirim:

    MyType mTrue = new MyType(100);
    MyType mFalse = new MyType(-100);
    MyType mDontKnow = new MyType(0);

    if (mTrue)
    {
         // Do something.
    }

    while (mFalse)
    {
        // Do something else.
    }

    do
    {
        // Another code comes here.
    } while (mDontKnow)

Ancak yukarıdaki tüm örnekler için yalnızca gerçek operatör çalıştırılır. Peki, C # 'daki yanlış operatör ne işe yarar?

Not: Daha fazla örnek burada , burada ve burada bulunabilir .


Modern belgeler docs.microsoft.com/en-us/dotnet/csharp/language-reference/… adresinde bulunabilir . Belgeler, C # 2.0 null atanabilir türler eklediğinden bu işleci tanımlamak için artık bir neden olmadığını gösteriyor.
Mark Amery

Yanıtlar:


65

&&Ve ||işleçlerini geçersiz kılmak için kullanabilirsiniz .

&&Ve ||operatörler geçersiz kılınan olamaz, ancak geçersiz kılarsanız |, &, trueve falsetam olarak doğru bir şekilde derleyici arayacak |ve &yazdığınız zaman ||ve &&.

Örneğin, şu koda bakın ( http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - bu numara hakkında öğrendiğim yer ; @BiggsTRC tarafından arşivlenmiş sürüm ):

public static AbstractCriterion operator &(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new AndExpression(lhs, rhs);
}

public static AbstractCriterion operator |(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new OrExpression(lhs, rhs);
}

public static bool operator false(AbstractCriterion criteria)
{
       return false;
}
public static bool operator true(AbstractCriterion criteria)
{
       return false;
}

Bu açıkça bir yan etkidir ve amaçlandığı şekilde değil, ancak faydalıdır.


Bağlantınız 404. Bunu nasıl düzenlemek istediğinizden emin değilim, bu yüzden bıraktım.
user7116

Hâlâ okunabilmesi için URL'yi arşivlenmiş bir kopya ile güncelledim.
IAmTimCorey

25

Shog9 ve Nir: Cevaplarınız için teşekkürler. Bu cevaplar beni işaret etti Steve Eichert maddeye ve beni işaret etti msdn :

X && y işlemi, T. yanlış (x)? x: T. & (x, y), burada T.false (x), T'de yanlış beyan edilen işlecin bir çağrısıdır ve T. & (x, y), seçilen & operatörünün bir çağrısıdır. Diğer bir deyişle, x'in kesinlikle yanlış olup olmadığını belirlemek için önce x değerlendirilir ve sonuçta yanlış operatörü çağrılır. O zaman, x kesinlikle yanlışsa, işlemin sonucu daha önce x için hesaplanan değerdir. Aksi takdirde, y değerlendirilir ve seçilen işleç, daha önce x için hesaplanan değerde ve y için hesaplanan değerde işlemin sonucunu üretmek üzere çağrılır.


Bunun (!T.true(x)) ? x : T.&(x, y)yerine neden mantığı kullanmayı seçmediklerini merak ediyorum .
Des Nerger

14

Http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx'e bağladığınız sayfa , bunların ne işe yaradığını söylüyor, bu da null yapılabilir değer türleri tanıtılmadan önce null yapılabilir bool'ları işlemenin bir yoluydu.

Sanırım bugünlerde ArrayList ile aynı tür şeyler için iyi - yani kesinlikle hiçbir şey.


7

AFAIK, &&operatör devreye girdiğinde olduğu gibi yanlış için bir testte kullanılacaktır . Unutmayın, && kısa devreler, yani ifadede

if ( mFalse && mTrue) 
{
   // ... something
}

mFalse.false()çağrılır ve döndükten truesonra ifade 'mFalse.true ()' çağrısına indirgenir (bu daha sonra geri dönmelidir false, yoksa işler tuhaflaşır).

Eğer uygulamaları gerektiğini Not &o takdirde kullanılan beri, derleme bu ifadesi için sırayla operatörü mFalse.false()getiri false.


3

Bağlandığınız MSDN makalesinden, Nullable (yani, int ?, bool?, Vb.) Türünün C # 2'de dile getirilmesinden önce null yapılabilir boole türlerine izin vermek için sağlandığı görülmektedir. Böylece, değerin doğru mu yanlış mı yoksa boş mu olduğunu gösteren dahili bir değer saklarsınız, yani örneğinizde doğru için> 0, yanlış için <0 ve null için == 0 ve sonra SQL tarzı boş anlambilim elde edersiniz. Ayrıca, geçersizliğin açıkça kontrol edilebilmesi için bir .IsNull yöntemi veya özelliği uygulamanız gerekir.

SQL ile karşılaştırıldığında, Foo değeri true olarak ayarlanmış 3 satır, Foo değeri false olarak ayarlanmış 3 satır ve Foo değeri null olarak ayarlanmış 3 satır içeren bir tablo Tablo düşünün.

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE
6

Tüm satırları saymak için aşağıdakileri yapmanız gerekir: -

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE OR Foo IS NULL
9

Bu 'IS NULL' sözdizimi, sınıfınızda .IsNull () olarak eşdeğer koda sahip olacaktır.

LINQ, C # ile karşılaştırmayı daha da netleştirir: -

int totalCount = (from s in MyTypeEnumerable
                 where s || !s
                 select s).Count();

MyTypeEnumberable'ın veritabanının tamamen aynı içeriğine sahip olduğunu hayal etmek, yani doğruya eşit 3 değer, yanlışa eşit 3 değer ve boş değere eşit 3 değer. Bu durumda totalCount, bu durumda 6 olarak değerlendirilir. Ancak kodu şu şekilde yeniden yazarsak: -

int totalCount = (from s in MyTypeEnumerable
                 where s || !s || s.IsNull()
                 select s).Count();

Daha sonra totalCount, 9 olarak değerlendirilir.

Yanlış işleçle ilgili bağlantılı MSDN makalesinde verilen DBNull örneği, BCL'de tam olarak bu davranışa sahip bir sınıf gösterir.

Aslında sonuç, bu tür bir davranışı istediğinizden tamamen emin olmadığınız sürece bunu kullanmamalısınız, sadece çok daha basit null atanabilir sözdizimini kullanmak daha iyidir!

Güncelleme: Mantık operatörlerini manuel olarak geçersiz kılmanız gerektiğini fark ettim!, || ve && bunun düzgün çalışmasını sağlamak için. Yanlış operatörün bu mantıksal operatörleri beslediğine inanıyorum, yani gerçeği, yanlışlığı veya "aksi" yi belirtiyor. Başka bir yorumda belirtildiği gibi! X yarasadan işe yaramaz; aşırı yüklemelisin! Tuhaflık!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.