यह मैं क्या कर सकता है:
एक अमूर्त वर्ग के रूप में रखें लिंक, एक फैक्टरी का उपयोग यह दृष्टांत और फैक्टरी के निर्माण विधि के लिए एक पैरामीटर के रूप में/गुमनाम विधि अपने बंद करने में पारित करने के लिए। इस तरह, आप अपने मूल डिजाइन को एक अमूर्त वर्ग के रूप में लिंक के साथ रख सकते हैं, कारखाने के माध्यम से कार्यान्वयन को मजबूर कर सकते हैं, और कारखाने के अंदर लिंक के किसी भी ठोस निशान को छुपा सकते हैं।
यहां कुछ उदाहरण कोड है:
class Program
{
static void Main(string[] args)
{
Link link = LinkFactory.GetLink("id",() =>
// This would be your onClick method.
{
// SetResponsePage(...);
Console.WriteLine("Clicked");
Console.ReadLine();
});
link.FireOnClick();
}
public static class LinkFactory
{
private class DerivedLink : Link
{
internal DerivedLink(String id, Action action)
{
this.ID = id;
this.OnClick = action;
}
}
public static Link GetLink(String id, Action onClick)
{
return new DerivedLink(id, onClick);
}
}
public abstract class Link
{
public void FireOnClick()
{
OnClick();
}
public String ID
{
get;
set;
}
public Action OnClick
{
get;
set;
}
}
}
संपादित करें: वास्तव में, यह करने के लिए एक छोटे से करीब तुम क्या चाहते हो सकता है:
Link link = new Link.Builder
{
OnClick =() =>
{
// SetResponsePage(...);
},
OnFoo =() =>
{
// Foo!
}
}.Build("id");
सौंदर्य यह एक init ब्लॉक का उपयोग करता है, आपको लिंक क्लास के भीतर कार्यों के कई वैकल्पिक कार्यान्वयन की घोषणा करने की इजाजत देता है।
यहां प्रासंगिक लिंक क्लास (सीलबंद बिल्डर आंतरिक कक्षा के साथ) है।
public class Link
{
public sealed class Builder
{
public Action OnClick;
public Action OnFoo;
public Link Build(String ID)
{
Link link = new Link(ID);
link.OnClick = this.OnClick;
link.OnFoo = this.OnFoo;
return link;
}
}
public Action OnClick;
public Action OnFoo;
public String ID
{
get;
set;
}
private Link(String ID)
{
this.ID = ID;
}
}
यह आप के लिए क्या देख रहे हैं के करीब है, लेकिन मुझे लगता है कि हम इसे वैकल्पिक नामित तर्क के साथ एक कदम आगे ले जा सकते हैं, एक सी # 4.0 सुविधा। चलिए वैकल्पिक नामित तर्कों के साथ लिंक की घोषणा की उदाहरण देखें:
Link link = Link.Builder.Build("id",
OnClick:() =>
{
// SetResponsePage(...);
Console.WriteLine("Click!");
},
OnFoo:() =>
{
Console.WriteLine("Foo!");
Console.ReadLine();
}
);
यह अच्छा क्यों है? की नई लिंक वर्ग पर नजर डालते हैं:
public class Link
{
public static class Builder
{
private static Action DefaultAction =() => Console.WriteLine("Action not set.");
public static Link Build(String ID, Action OnClick = null, Action OnFoo = null, Action OnBar = null)
{
return new Link(ID, OnClick == null ? DefaultAction : OnClick, OnFoo == null ? DefaultAction : OnFoo, OnBar == null ? DefaultAction : OnBar);
}
}
public Action OnClick;
public Action OnFoo;
public Action OnBar;
public String ID
{
get;
set;
}
private Link(String ID, Action Click, Action Foo, Action Bar)
{
this.ID = ID;
this.OnClick = Click;
this.OnFoo = Foo;
this.OnBar = Bar;
}
}
स्थिर वर्ग बिल्डर के अंदर, वहाँ एक कारखाने विधि बिल्ड कि 1 आवश्यक पैरामीटर (आईडी) और 3 वैकल्पिक पैरामीटर, OnClick, OnFoo और OnBar में ले जाता है। अगर उन्हें असाइन नहीं किया गया है, तो फैक्ट्री विधि उन्हें एक डिफ़ॉल्ट कार्यान्वयन देती है।
तो लिंक के लिए आपके कन्स्ट्रक्टर के पैरामीटर तर्कों में, आपको केवल उन्हीं विधियों को लागू करने की आवश्यकता है, अन्यथा वे डिफ़ॉल्ट कार्रवाई का उपयोग करेंगे, जो कुछ भी नहीं हो सकता है।
हालांकि, अंतिम उदाहरण में दोष, सारणी सार सारणी नहीं है। लेकिन इसे लिंक क्लास के दायरे से बाहर नहीं किया जा सकता है, क्योंकि इसका कन्स्ट्रक्टर निजी है (लिंक को चालू करने के लिए बिल्डर क्लास के उपयोग को मजबूर करना)।
आप वैकल्पिक पैरामीटर को सीधे एक कारखाने की आवश्यकता से परहेज करते हुए सीधे लिंक के कन्स्ट्रक्टर में स्थानांतरित कर सकते हैं।
मुझे आपके द्वारा दिए गए उदाहरण में अज्ञात आंतरिक वर्ग नहीं दिख रहा है। यदि आप अपने अमूर्त वर्ग के कार्यान्वयनकर्ताओं को हमेशा कुछ तरीकों को लागू करने के लिए चाहते हैं तो आप कक्षा में एक अमूर्त विधि बना सकते हैं या इसे एक इंटरफेस लागू कर सकते हैं। – tenor
@tenor, एक इनलाइन अज्ञात वर्ग परिभाषित किया गया है जो 'लिंक' से विरासत में मिलता है और 'onClick' विधि को ओवरराइड करता है। जावा के विपरीत, सी # किसी दिए गए उपयोगकर्ता प्रकार से प्राप्त करने के लिए अज्ञात कक्षाओं का समर्थन नहीं करता है। –
@ डारिन डिमिट्रोव, यह इंगित करने के लिए धन्यवाद। मैं एक सच्चे "आंतरिक/घोंसला" वर्ग की तलाश में था। प्रदान किया गया उदाहरण एक अज्ञात वर्ग की तरह दिखता है जो कम से कम सी # लिंगो में मौजूदा वर्ग से निकला है। – tenor