2009-10-01 13 views
8

मैं सोच रहा हूं कि ऐसा करने में सक्षम होना उपयोगी होगा, उदाहरण के लिए, शून्य संदर्भों के लिए पैरामीटर की जांच करने और अंततः अपवाद फेंकने के लिए।
यह कुछ टाइपिंग को बचाएगा और यदि कोई नया पैरामीटर जोड़ा गया है तो चेक जोड़ने के लिए भी भूलना असंभव हो जाएगा।क्या सी # में विधि के पैरामीटर के माध्यम से पुनरावृत्ति करना संभव है?

उत्तर

15

ठीक है, नहीं जब तक आप गिनती:

public void Foo(string x, object y, Stream z, int a) 
{ 
    CheckNotNull(x, y, z); 
    ... 
} 

public static void CheckNotNull(params object[] values) 
{ 
    foreach (object x in values) 
    { 
     if (x == null) 
     { 
      throw new ArgumentNullException(); 
     } 
    } 
} 

सरणी निर्माण हिट बचने के लिए आप तर्क की विभिन्न संख्या के लिए भार के के एक नंबर हो सकता है:

public static void CheckNotNull(object x, object y) 
{ 
    if (x == null || y == null) 
    { 
     throw new ArgumentNullException(); 
    } 
} 

// etc 

एक वैकल्पिक करने के लिए किया जाएगा यह घोषणा करने के लिए गुणों का उपयोग करें कि पैरामीटर शून्य नहीं हो सकते हैं, और उचित जांच उत्पन्न करने के लिए PostSharp प्राप्त करें:

public void Foo([NotNull] string x, [NotNull] object y, 
       [NotNull] Stream z, int a) 
{ 
    // PostSharp would inject the code here. 
} 

मान्य रूप से मैं शायद पोस्टशर्प को Code Contracts कॉल में परिवर्तित करने के लिए चाहता हूं, लेकिन मुझे नहीं पता कि दोनों एक साथ कितनी अच्छी तरह खेलते हैं। हो सकता है कि एक दिन हम युक्ति # की तरह लिखने के लिए सक्षम हो जाएगा:

public void Foo(string! x, object! y, Stream! z, int a) 
{ 
    // Compiler would generate Code Contracts calls here 
} 

... लेकिन निकट भविष्य :)

+0

आपके मामले में क्या CheckNotNull ((वस्तु []) नल) के बारे में? :-) –

+1

सोचें कि लेखक का अर्थ जावास्क्रिप्ट के तर्कों की तरह कुछ है। जैसे "फू (स्ट्रिंग एक्स, ऑब्जेक्ट वाई, स्ट्रीम जेड, इंट ए)" विधि में सभी तर्कों को सूचीबद्ध करें और उनमें से प्रत्येक को निर्दिष्ट किये बिना उन्हें शून्य के लिए जांचें, लेकिन "सामान्य प्रमाणीकरण (Foo.arguments) जैसे कुछ सामान्य विधि पर कॉल करें;" । – Kamarey

+0

@Dzmitry: ठीक है, हाँ - आप अभी तक काफी उत्पादन तैयार नहीं हैं :) –

0

यह पैरामीटर है कि एक विधि (प्रतिबिंब के माध्यम से) के लिए घोषित किया गया है से अधिक पुनरावृति करने के लिए संभव है, लेकिन मैं एक विशिष्ट विधि कॉल के लिए उन मापदंडों का मान प्राप्त करने के लिए कोई रास्ता नहीं देख ...

शायद आप Postsharp का उपयोग कर सकते हैं, और आप इस चेक को कहां करते हैं, इसमें एक पहलू बनाएं। फिर, संकलन समय पर, Postsharp 'बुनाई' पहलू हर विधि है कि आप लिखित दिया है पर (अतिरिक्त कोड इंजेक्षन) कर सकते हैं ...

0

आप The Validation Application Block जो स्वचालित सत्यापन और The Unity Application Block का एक उदाहरण के रूप में इलाज किया जा सकता पर गौर कर सकते (विशेष रूप से इसकी अवरोध सुविधा) कॉल को अवरुद्ध करने और निरीक्षण मानकों के संबंध में।

2

में नहीं तुम एक params कीवर्ड के साथ विधि पैरामीटर परिभाषित कर सकते हैं। यह आपकी विधि में पैरामीटर की एक चर-लंबाई संख्या को पारित करना संभव कर देगा। फिर आप उन पर पुन: प्रयास कर सकते हैं और शून्य संदर्भों की जांच कर सकते हैं या जो भी आप चाहते हैं।

public void MyMethod(params object[] parameters) { 
    foreach (var p in parameters) { 
     ... 
    } 
} 

// method call: 
this.MyMethod("foo", "bar", 123, null, new MyClass()); 

मेरी राय में हालांकि, यह चीजों को करने का एक अच्छा तरीका नहीं है। आपको अपने पैरामीटर के प्रकार को मैन्युअल रूप से नियंत्रित करना होगा, इनपुट सरणी में उनकी स्थिति और आप विजुअल स्टूडियो में उनके लिए इंटेलिजेंस का उपयोग करने में सक्षम नहीं होंगे।

0

आप शायद AOP लाइब्रेरी जैसे PostSharp के साथ पैरामीटर जांच स्वचालित कर सकते हैं।

1

मेरे पास कुछ समय पहले एक ही सवाल था, लेकिन लॉगिंग उद्देश्यों के लिए ऐसा करना चाहता था। मुझे कभी भी एक अच्छा समाधान नहीं मिला, लेकिन लॉगिंग विधि प्रविष्टियों और बाहर निकलने के लिए एओपी आधारित दृष्टिकोण का उपयोग करने के संबंध में यह लिंक मिला। इसके बारे में एक ऐसा ढांचा उपयोग करने की आवश्यकता है जो आपकी कक्षा को पढ़ सके और रनटाइम पर कोड इंजेक्ट करे जो आप करने की कोशिश कर रहे हैं। आसान नहीं लगता है।

How do I intercept a method call in C#?

0

एक विधि params कीवर्ड का उपयोग करने का एक तुच्छ उदाहरण देने के बाद, RaYell का कहना है:

मेरी राय में हालांकि, यह काम करने के लिए एक अच्छा तरीका नहीं है। आपको को अपने पैरामीटर के प्रकार को मैन्युअल रूप से नियंत्रित करना होगा, इनपुट सरणी में उनकी स्थिति और आप विज़ुअल स्टूडियो में उनके लिए इंटेलिजेंस का उपयोग करने में सक्षम नहीं होंगे।

मैं करूंगा निश्चित रूप से सहमत हैं कि एक विधि है कि दो strings, एक int लेता है, एक object है कि रिक्त हो सकता है, और एक अन्य MyClass वस्तु params का उपयोग कर की घोषणा एक बुरा विचार है। हालांकि, (मेरी राय में) params कीवर्ड के पूरी तरह से वैध और उचित अनुप्रयोग हैं, अर्थात् जब पैरामीटर एक ही प्रकार के होते हैं। उदाहरण के लिए:

public T Max<T>(T x, T y) where T : IComparable<T> { 
    return x.CompareTo(y) > 0 ? x : y; 
} 

public T Max<T>(params T[] values) where T : IComparable<T> { 
    T maxValue = values[0]; 

    for (int i = 1; i < values.Length; i++) { 
     maxValue = Max<T>(maxValue, values[i]); 
    } 

    return maxValue; 
} 
0
var mandatoryFields = (new object[] { input1, input2 }).Where(v => v == null || v.ToString().Trim() == ""); 

आप अशक्त मानकों की सूची प्राप्त होगा।

तो फिर तुम सिर्फ जोड़ सकते हैं

if(mandatoryFields.ToArray().Count > 0){} 
संबंधित मुद्दे

 संबंधित मुद्दे