2009-04-30 22 views
22

Aşağıdaki kodum var:C# Derleyici: statik olmayan bir bağlamda statik yönteme erişemiyor

public class Anything 
{ 
    public int Data { get; set;} 
} 

public class MyGenericBase<T> 
{ 
    public void InstanceMethod(T data) 
    { 
     // do some job 
    } 

    public static void StaticMethod(T data) 
    { 
     // do some job 
    } 

    // others members... 
} 

public sealed class UsefulController : MyGenericBase<Anything> 
{ 
    public void ProxyToStaticMethod() 
    { 
     StaticMethod(null); 
    } 

    // others non derived members... 
} 

public class Container 
{ 
    public UsefulController B { get; set; } 
} 

public class Demo 
{ 
    public static void Test() 
    { 
     var c = new Container(); 
     c.B.InstanceMethod(null); // Works as expected. 
     c.B.StaticMethod(null);  // Doesn't work. 
            // Static method call on object rather than type. 
            // How to get the static method on the base type ? 
     c.B.ProxyToStaticMethod(); // Works as expected. 
    } 
} 

Derleyici çok kızgın ... Hata mesajını anlıyorum ama nasıl çözeceğimi bilmiyorum. Statik yöntem çağrımı yapmak için bir nesne yerine bir tür almaya çalışıyordum, ancak bunu doğru şekilde yapmanın bir yolunu bulamıyorum. Üstelik bu, hiç de şık olmayan bir şeyle sonuçlanır.

Temel olarak, GenericBase bir çok statik yöntem ve bazı örnek yöntemleri olan bir çerçeveden bir sınıftır. Denetleyici bu sınıfı yazıyor ve genişletiyor.

Kapsayıcı, bir grup mantıksal ilişkili denetleyicidir.

İlginç bir şey: bu kodun bir Java sürümü doğru şekilde derleniyor, ancak bir uyarı ile. Yürütme de doğru.

Bunu çözmek için bir tasarım deseni var mı?

Girişleriniz için teşekkürler!


Bu problemden kurtulmanın bir yolu buldum, cevaplarınız sayesinde. Çalışıyor gibi görünüyor, ancak bildiğim yan etkilerin olup olmadığını anlayamıyorum.

 public class GenericBase<T> : MyGenericBase<T> 
{ 
    // Create instance calls here for every base static method. 
} 

public sealed class UsefulController : GenericBase<Anything> 
{ 
    // others non derived members... 
} 

cevap

26

Belirli bir sınıfta belirli bir statik yöntemi çağırmak için statik yöntem çağrısı derlenecektir. Diğer bir deyişle, hangi statik yöntemin kullanılacağını belirlemek için B içeriğini kullanmaz.

Bu nedenle çağrı derleme zamanında çözülebilir olmalı, dolayısıyla şikayet ediyor, çünkü tüm bildiği için, o mülkün içeriğini birden fazla beton türü ile değiştirebilirdiniz, bu da statik yönteme yapılan çağrının Bu sınıflardan herhangi birinde statik bir yönteme çözümlenecek.

Derleyici, sanal veya soyut statik bir yöntem gibi bir şeye sahip değildir, bu nedenle, tüm bu sınıfların bu statik yönteme sahip olduğunu garanti edemezsiniz. Ve çağrı derleme zamanında çözülebilir olması gerektiğinden, bu şekilde çalışmayacaktır.

Fark ettiğiniz gibi, durağan yöntemi çağıran nesnenin örnek yöntemini çağırabilirsiniz. Bu, yukarıdaki kuralı geçersiz kılmaz çünkü derleyici bu örnek yöntemini derlediğinde, hangi statik yöntem kullanacağı sürekli ve bilinir.

+0

Çok öğretici, teşekkürler!Aşağıda cevapları okumak, olası bir çözüm hakkında merak ediyorum. Yorum yapmaktan çekinmeyin. –

+0

sonuçta, – BlackTigerX

2

Bunu C# yapamazsınız. Bunu VB.NET ve Java'da yapabilirsin, ama dürüst olmak gerekirse, gerçekten mantıklı değil. Hiçbir şekilde gerçek olmayan bir static yönteminde yanlış bir polimorfizm duygusu verir. Polimorfik olmadığından, tüm yöntem çağrısı derleme zamanında bilinir (statik olarak) ve çağrıyı doğrudan sınıf adıyla anlayabilirsiniz.

9

Statik yöntemi çağırmak için, o sınıfın bir örneğinde değil, tanımlandığı sınıftan başvurmanız gerekir.

MyGenericBase<Anything>.StaticMethod(null); 
+0

hiçbir şey için STATIC denir değil! Bunu zaten farkettim. Bu çağrıları konteynırdan yapmanın bir yolunu arıyorum. İlk önce temel sınıfı örnek yöntemlerini statik yöntemlere dahil edecek başka bir tabana türetmeyi ne dersiniz? –

1

Onlardan birini yapabilirsiniz:

UsefulController.StaticMethod(null); 
MyGenericBase<Anything>.StaticMethod(null); 

zaten başkaları tarafından açıklandığı gibi örneğini kullanarak, mümkün değildir.

+0

Teşekkürler! Bunu zaten farkettim. Bu çağrıları konteynırdan yapmanın bir yolunu arıyorum. İlk önce temel sınıfı örnek yöntemlerini statik yöntemlere dahil edecek başka bir tabana türetmeyi ne dersiniz? –

+0

Bu örnek çağrısına "ihtiyacınız olduğunu" düşünüyorsanız, yalnızca proxy yönteminizi ekleyin. Tavsiyem, API'yi temiz ve açık tutmak için çalışmaktır. – Lucero

+0

İçindekiler sınıfını kullanarak statik üyeleri doğrudan arayamadığım için, şimdilik tek çözüm olduğu görülüyor. API'yi olabildiğince temiz tutmayı kabul ediyorum. –

İlgili konular