2011-11-23 10 views
21

aşağıdaki F # kodu tabanı ve soyundan sınıfları beyan gelen aşırı edilmiş bir F # yöntemini çözülemiyor. Temel sınıf, varsayılan bir implementaion ile sanal bir yönteme sahiptir. Alt sınıf, temel sınıf yöntemini geçersiz kılar ve ayrıca yeni bir aşırı yüklenmiş 'Test' yöntemi ekler. Bu kod, iyi derlenmiş ve 'Test' yöntemlerinden birine erişirken sorun oluşturmaz.hem geçersiz kılınmış ve C#

F # Kod:

var result = td.Test(3); <- No overload for method 'Test' takes 1 arguments

tam C# Kod:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Client 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     var td = new OverrideTest.Descendant(); 
     var result = td.Test(3); 
     Console.WriteLine(result); 
     Console.ReadKey(); 
    } 
    } 
} 
bir derleme hatası C# sonuçlarından 'Testi' soyundan geçersiz kılmasını yakalamaya çalıştığını Ancak

module OverrideTest 
    [<AbstractClass>] 
    type Base() = 
    abstract member Test : int -> int 
    default this.Test x = x + 1 

    type Descendant() = 
    inherit Base() 
    override this.Test x = x - 1 
    member this.Test (x, y) = x - y 

,

Tuhaf olan şey, VisualStudio'nun intellisense'in aşırı yüklenmiş iki işlevi görmesi ve her ikisi için de doğru imzalar. Yapı başarısız olmadan önce herhangi bir uyarı veya hata vermez ve sadece çizgiyi daha sonra vurgular.

C# tam bu senaryoyu yeniden hayata geçirdik ve aynı sorun haline çalıştırmak vermedi.

Herkes burada neler olduğunu herhangi bir fikir var mı? veya basitçe Test2(x,y) adlandırmak - -

+0

Yayımlanan IL'yi her iki dilde mi karşılaştırdınız? – Oded

+0

C# kodunda, yöntemi çağırmadan önce temel sınıfa girdiğinizde ne olur? – Brian

+0

@Brian: Bu işe yarıyor. – Daniel

cevap

17

Hayır sen Descendant türünden Test(x,y) üyesi atlarsanız farkındayız şüphe sonra C# kodu derlemek ve beklendiği gibi çalışır. Test(x,y) yöntem üzerinde hiçbir hidebysig nitelik var ki

.method public hidebysig virtual 
    instance int32 Test (
     int32 x 
    ) cil managed ... 

.method public 
    instance int32 Test (
     int32 x, 
     int32 y 
    ) cil managed ... 

Uyarı: Orijinal Descendant türü için oluşturulan IL baktığımızda

bir ipucu sunmaktadır.

ECMA CLI specification yaklaşık hidebysig söylenecek aşağıdaki sahiptir. (Bölüm 15.4.2.2, kalın vurgu bana ait.)

hidebysig is supplied for the use of tools and is ignored by the VES. It specifies that the declared method hides all methods of the base class types that have a matching method signature; when omitted, the method should hide all methods of the same name, regardless of the signature.

Yani, F # derleyici hidebysig niteliğini atlar, Test(x,y) yöntem Test adlı tüm diğer yöntemleri gizler anlamına gelir. hidebysig yalnızca "araçların kullanımı için" olmasına rağmen, C# derleyicisinin onu kullanan araçlardan biri olduğu anlaşılıyor! o F # derleyicisi bir hata olabilir gibi

Bu benim için görünüyor, ama ben F # spec baktım hiç çünkü bu/Belirtilen davranışı izin verildiğini her zaman mümkündür.

+0

+1: Bir kaç kez okuyup okumak zorundaydık. IMO'nun cümlenin son kısmı da ** BOLD ** olmalıdır. – leppie

+0

Bu bir hata olmak için _got_. Sağ? – Daniel

+0

@Daniel: hidebysig'in neden ihmal edilmesi gerektiğini düşünemiyorum. (Bunu hiç bilmiyordum) – leppie