2009-10-31 19 views
5

Bu bir CLR kısıtlaması mı yoksa bir dil tasarımı kararı mı? Ben C bunu yapmaya çalıştım ++/CLI, gerek yerli C++ desteklemek için çünkü çalışır elbette:Neden C# destek operatörü aşırı yükleme yapmıyor?

public ref class Test 
    { 
     public: 
     static Test^ operator &(Test^ msg, int& i) 
     { 
      i = i + 1; 

      return nullptr; 
     } 
    }; 

ve sonra derleyici ihmal çıkışında baktı: Ben daha da ileri giderek

public: static Test __gc* op_BitwiseAnd(Test __gc* msg, Int32 __gc** modopt(IsImplicitlyDereferenced __gc*) i) 
{ 
    i[0] += 1; 
    return 0; 
} 

ve C# projeden Bu operatörü aramaya çalıştım - ve tabii ki ben [güvensiz] bunu yapmak (ı gerekli işaretçi) gitmek için gerekli: CLR için uygulamaya Açıkçası o kadar zor

Test t = new Test(); 
int i = 0; 

unsafe 
{ 
    t = t & &i; 
} 

? Operatörlerin aşırı yüklenmesi konusunda referansları kaçırdım ve en azından ışığında kendimi neden bu kadar özlüyorum?

Neden Operatör aşırı yüklerimizde referans değişkenler ile uğraşmamız gerektiğinde, güvensiz ve işaretçilerin ardındaki çirkinliği C# gizleyemiyoruz? Bu çirkin geçici çözümle devam etmeyi seçsem bile, güvenli olmayan işlemlere izin verilmeyen Silverlight'ta çalışmayacak olsaydım ...

cevap

5

C# 'da, değişkenleriniz referans olarak (örn. int.TryParse(s, out i)out anahtar kelimesini açıkça belirtirsiniz). Bu özellik, aşırı yüklenen operatörün açık izniniz olmadan işlenenlerin içeriğini değiştirmesine izin vererek işleri karmaşıklaştıracaktır.

MyStruct x = new MyStruct(); 
MyStruct y = new MyStruct(); 
MyStruct z = x + y; // in C#, you never expect `x` to be changed. 
+0

Hiç de değil. Sadece ref parametresini almak için operatör aşırı yükleme yapmak? –

+0

Ivan: o zaman aşırı yüklenen operatörü nasıl çağırırsınız? Bir yöntem bir "ref" parametresini alırsa, arama sitesi ** ve ** tanım sitesi ** açık bir şekilde ** parametreyi "ref" olarak bildirmelidir. –

+0

Mehrdad: Bu kesinlikle sorun değil. Farklı imzası var, bu yüzden ref olmadan arama hiçbir zaman aşırı yüklenmeyle eşleşmeyecektir. Bununla ilgili ne kadar karmaşık bir şey var ki, bu C# takımını uygulamamıştır? Bir referans türü olmayan bir işleneni değiştirmem gerekirse ne yapmalıyım? –

1

Ben bir operatör (C# almak gibi görünüyor daha matematiksel görünümünde) bunun nedeni düşünüyorum:

public static MyStruct operator + (ref MyStruct left, ref MyStruct right) { 
    left = new MyStruct(); // !!!!!!!! 
    return something(left, right); 
} 

C# böyle bir operatör başvuru Örneğin

, Mantıksal olarak, argümanlarını yeni bir değere birleştiren, hiçbir zaman bir şeyleri dönüştürmemesi gereken bir şey. C++, işletmecileri, özellikle matematikleri temsil etmenin bir yolu olmaktan ziyade, fonksiyonlardan daha uygun bir sözdizimi ile genel operasyonların bir versiyonu olarak görmektedir. Sanırım C# 'da neredeyse hiçbir zaman akış operasyonları için operatörleri tanımlamak gibi şeyler görmeyeceksiniz.