Bu yüzden asp.net mvc'de ui denetimleri üretmek için bir nesne hiyerarşisi alıyorum ve akıcı bir api elde etmeye çalışıyorum. Mevcut probleme odaklanmak için kukla bir sınıf yapıyorum..NET'te uzantı yöntemleri nasıl "geçersiz kılınır"?
LinkButton lb = new LinkButton().Id("asd");
Gerçekten derleyici seçmek düşündüm: Ben bir LinkButton üzerinde kimliği aramaya çalıştığımda
public abstract class HtmlElement { /* ... */ }
public abstract class UIElement : HtmlElement { /* ... */ }
public abstract class ButtonBase : UIElement { /* ... */ }
public class LinkButton : ButtonBase { /* ... */ }
public class ActionButton : ButtonBase { /* ... */ }
public static class HtmlElementExtensions
{
public static T Id<T>(this T item, string id) where T : HtmlElement
{
/* set the id */
return item;
}
}
public static class ButtonBaseExtensions
{
public static T Id<T>(this T item, string id) where T : ButtonBase
{
/* set the id and do some button specific stuff*/
return item;
}
}
derleyici belirsiz çağrı var diyor ki: Yani burada
"yanlış" kod temeli Bu durumda en yakın eşleşme, HtmlElement öğesinden devraldığı HtmlExtensions Id yönteminden devralınan bir Komut Dosyası sınıfına sahip olsaydım ve bir Bağlama Düğmesi için (kısıtlamalardan dolayı) ButtonBase yöntemi çağrılır. Bir çözümüm var, ama daha iyi bir tane olduğundan emin değilim.
I ButtonBaseExtensions id silme yöntemi ve aşağıdaki şekilde olduğu gibi HtmlElementExtensions Id yöntemi değiştirilebilir:
public static T Id<T>(this T item, string id) where T : HtmlElement
{
if (item is ButtonBase)
{
/* do some button specific stuff*/
}
/* set the id */
return item;
}
Bu şekilde ButtonBase her sınıf soyundan çalışmaktadır. Çözümü gerçekten beğenmedim, çünkü HtmlElement mantığını ButtonBase mantığıyla karıştırıyor. Daha iyi bir çözüm için herhangi bir fikir/öneri? Onları farklı ad alanına koydum sanırım, ama sadece bir saniye. Her iki isim alanını da kullanmalıyım, bu yüzden sorunu çözmeyin.
Derleyicinin genel uzantı yöntemleri üzerindeki kısıtlamaları izlemesinin gerektiği fikri olarak msdn forumlarından bahsetmeye değer olduğunu mu düşünüyorsunuz? Bu arada
Biraz daha araştırma yapmak ve msdn forumlarında bir iplik başlamak:
link Bazı olmayan jenerik uzatma methodds çalıştı:
BaseClass bc = new BaseClass();
InheritedClass ic = new InheritedClass();
BaseClass ic_as_bc = new InheritedClass();
bc.SomeMethod("bc");
ic.SomeMethod("ic");
ic_as_bc.SomeMethod("ic_as_bc");
:
public class BaseClass { /*...*/ }
public class InheritedClass : BaseClass { /*...*/ }
public static class BaseClassExtensions
{
public static void SomeMethod(this BaseClass item, string someParameter)
{
Console.WriteLine(string.Format("BaseClassExtensions.SomeMethod called wtih parameter: {0}", someParameter));
}
}
public static class InheritedClassExtensions
{
public static void SomeMethod(this InheritedClass item, string someParameter)
{
Console.WriteLine(string.Format("InheritedClassExtensions.SomeMethod called wtih parameter: {0}", someParameter));
}
}
Ve ben bu örneğini ise
Bu çıktı üretildi:
BaseClassExtensions.SomeMethod called wtih parameter: bc
InheritedClassExtensions.SomeMethod called wtih parameter: ic
BaseClassExtensions.SomeMethod called wtih parameter: ic_as_bc
sayesinde
Péter
bir uzantısı yöntemi ** ** Bir sanal yöntemi için yedek oyuncu, ne de sanal yapılabilir değildir. Bu sınıfları kendiniz ilan ettiğin için, neden ihtiyacın olduğu belli değil. Sadece temel sınıflardan birine sanal bir yöntem ekleyin ve gerektiğinde türetilmiş bir sınıfta geçersiz kılın. –
Akıcı api nedeniyle uzatma yöntemleri kullanmam gerekiyor. Jenerik kalıtım sadece 2 seviyeli kalıtsallıkla çalışır. Derleyicinin çağırmak için doğru yöntemi belirlemek için parametre kısıtlamasını kullandığı, genetik olmayan uzantı yöntemiyle bir örnek yazdım. Derleyicinin genel parametre kısıtlamalarını da değerlendirmesini dilerim. Genel Statik T Id (bu T öğesi, dize kimliği) yerine "public Statik ButtonBase Kimliği" (bu ButtonBase öğesi, string id) yazamıyorum. Burada T: ButtonBase "dönüş tipi ButtonBase olacağından akıcı api'nin yöntem zinciri. –