ऐसा लगता है कि सी # भाषा डिजाइनरों ने अभी कुछ नहीं सोचा था। आप (और मैं) फ़ेक्स/प्रतिनिधि के लिए एक संकलन-समय "इंटरफ़ेस" ढूंढ रहे हैं, इसलिए उन्हें अनिवार्य रूप से संग्रह में उपयोग किया जा सकता है।
new[] {
new Func<MaxLengthAttribute, string>(a => "maxlength=" + a.Length),
new Func<RequiredAttribute, string>(a => "required")
}
केवल प्रारूप Func<out Attribute, string>
की Funcs पास करने के लिए:
अपने सवाल पूछने का का एक और तरीका है कि कैसे मैं किसी को इस तरह एक सरणी गुजर विवश करते है? सरल होना चाहिए ... नहीं?
नहीं। जैसा कि अन्य उत्तर से जुड़ा हुआ है, इनपुट पैरामीटर पर आउट कीवर्ड की अनुमति नहीं है जैसे कि हम यहां उपयोग कर रहे हैं।
आप संकलन समय आप जावा की तरह बदसूरत कलाबाजी के साथ फंस रहे हैं पर बाधा होना आवश्यक हैं:
public void CheckMethod(IHasMethod methodHaver)
{
}
Eugh:
public interface IHasMethod<T>
where T : BaseClass
{
void MethodToCheck<T>(T, object);
}
public class Class1 : IHasMethod<DerivedClass>
{
public object MethodToCheck(DerivedClass d)
{
}
}
अपने परीक्षण अर्थ की तरह दिखता है। इसी तरह मेरा सरणी उदाहरण बन जाता है: new IHasMethod[]
यदि आप सुंदर, अधिक चमकदार कोड पसंद करते हैं जो रन-टाइम पर केवल संरक्षित/निरीक्षण किया जाता है तो आपका विकल्प Delegate
है।आपके हस्ताक्षर:
public void CheckMethod(Delegate func)
मेरे सरणी उदाहरण:
new Delegate[] ...
लेकिन दोनों ही मामलों आप खतरे में हैं, क्योंकि है कि प्रतिनिधि के प्रारूप संकलन समय पर असीम है में - यह आप पर अब क्या करना चाहिए आमतौर पर करते हैं आगे बढ़ने से पहले संकलक की सही संख्या और पैरामीटर की सही संख्या की जांच, संकलक की समस्या हो। यदि आप कर सकते हैं, तो केवल डीबग कोड में बदसूरत जांच करने और यूनिट टेस्ट के लिए निकाली गई विधि के लिए कोई भी कॉल करने की कोशिश करें, भले ही आपने संकलन-सुरक्षा खो दी हो, फिर भी आप इसे स्वचालित परीक्षण सुरक्षा के साथ बदल दें। जैसा:
#if DEBUG
foreach(var attrTempl in attributeTemplates)
{
var templParams = attrTempl.Method.GetParameters();
if (templParams.Length != 1)
throw new Exception("Can't have " + templParams.Length + " params in AttributeTemplate Delegate, must be Func<out Attribute, string>");
var type1 = templParams[0].ParameterType;
var type2 = attrTempl.Method.ReturnType;
if (!type1.IsSubclassOf(typeof(System.Attribute)))
throw new Exception("Input parameter type " + type1.Name + " must inherit from System.Attribute");
if (type2 != typeof(string))
throw new Exception("Output parameter type " + type2.Name + " must be string");
}
#endif
इस में बाधा दौड़ के लिए एक आखिरी सहायक:
Func<A, B> fn
इस के लिए
:
Delegate fn
आप
Delegate
तरीका अपनाते हैं तो आप कोड है कि इस तरह दिखता है बदल देंगे
शायद आप किसी बिंदु पर फनक पर कॉल करें, जैसे:
var b = fn(a);
जो अब एक संकलन त्रुटि प्राप्त करेगा, क्योंकि संकलक सटीक रूप से दावा करता है कि यह प्रतिनिधि किसी भी पैरामीटर को स्वीकार नहीं करता है। लवली। आप के साथ अतीत में यह करने के लिए रन-टाइम बाज़ी कर सकते हैं:
var b = (B)fn.DynamicInvoke(a);
Related
मैं करने के लिए कारण है कि आप एक पूरी तरह से समस्या का समाधान जेनरिक का उपयोग कर के रूप में उत्सुक हूँ, लेकिन आप जा रहा है केवल मापदंड के साथ एक अलग समाधान के लिए देख रहे हैं कि इसे कम टाइपिंग की आवश्यकता होनी चाहिए। आपका लक्ष्य यहाँ क्या है? अपनी प्रोग्रामिंग टीम में आरएसआई को कम करना? –
मुख्य कारण यह है कि मुझे केवल वास्तविक विधि में दिलचस्पी है। लेकिन, तर्क और वापसी डेटा विधि हस्ताक्षर का एक हिस्सा है, इसलिए मुझे लगता है कि यह संभव नहीं है। –
यह वही है जो मैंने अपनी पोस्ट में कहा था :)। मुझे लगता है कि उत्तर के रूप में चिह्नित किया जाना चाहिए। –