मार्कर इंटरफ़ेस का उद्देश्य क्या है?


जवाबों:


77

यह "मिच गेहूं" की प्रतिक्रिया के आधार पर एक स्पर्शरेखा है।

आमतौर पर, जब भी मैं लोगों को फ्रेमवर्क डिज़ाइन दिशानिर्देशों का हवाला देता हूं, मैं हमेशा इसका उल्लेख करना चाहता हूं:

आपको आमतौर पर ज्यादातर समय रूपरेखा डिजाइन दिशानिर्देशों को अनदेखा करना चाहिए।

यह फ्रेमवर्क डिज़ाइन दिशानिर्देशों के साथ किसी भी समस्या के कारण नहीं है। मुझे लगता है कि .NET फ्रेमवर्क एक शानदार क्लास लाइब्रेरी है। फ्रेमवर्क डिज़ाइन दिशानिर्देशों से बहुत सारी शानदारता बहती है।

हालाँकि, डिज़ाइन दिशानिर्देश अधिकांश प्रोग्रामर द्वारा लिखे गए अधिकांश कोड पर लागू नहीं होते हैं। उनका उद्देश्य लाखों डेवलपर्स द्वारा उपयोग किए जाने वाले एक बड़े ढांचे के निर्माण को सक्षम करना है, न कि पुस्तकालय लेखन को अधिक कुशल बनाना।

इसमें बहुत सारे सुझाव आपको उन चीजों को करने के लिए मार्गदर्शन कर सकते हैं जो:

  1. कुछ को लागू करने का सबसे सीधा तरीका नहीं हो सकता है
  2. अतिरिक्त कोड दोहराव में परिणाम हो सकता है
  3. अतिरिक्त रनवे ओवरहेड हो सकता है

.Net फ्रेमवर्क बड़ा है, वास्तव में बड़ा है। यह इतना बड़ा है कि यह मानना ​​बिल्कुल अनुचित होगा कि किसी को भी इसके हर पहलू के बारे में विस्तृत जानकारी है। वास्तव में, यह मान लेना अधिक सुरक्षित है कि अधिकांश प्रोग्रामर अक्सर उस ढांचे के कुछ हिस्सों का सामना करते हैं जो उन्होंने पहले कभी इस्तेमाल नहीं किया है।

उस स्थिति में, API डिज़ाइनर के प्राथमिक लक्ष्य निम्न हैं:

  1. बाकी ढांचे के अनुरूप चीजें रखें
  2. एपीआई सतह क्षेत्र में अनावश्यक जटिलता को हटा दें

फ्रेमवर्क डिज़ाइन दिशानिर्देश उन लक्ष्यों को पूरा करने वाले कोड बनाने के लिए डेवलपर्स को धक्का देते हैं।

इसका मतलब है कि विरासत की परतों से बचने जैसी चीजें करना, भले ही इसका मतलब कोड को डुप्लिकेट करना हो, या साझा सहायकों का उपयोग करने के बजाय सभी अपवाद कोड को "प्रवेश बिंदु" पर धकेलना हो (ताकि स्टैक के निशान डीबगर में अधिक समझ में आए), और बहुत कुछ इसी तरह की अन्य चीजों के बारे में।

प्राथमिक दिशानिर्देश जो उन दिशानिर्देशों को मार्कर इंटरफेस के बजाय विशेषताओं का उपयोग करने का सुझाव देते हैं, क्योंकि मार्कर इंटरफेस को हटाने से कक्षा पुस्तकालय की विरासत संरचना बहुत अधिक अप्राप्य हो जाती है। 15 प्रकार और पदानुक्रम की 2 परतों के साथ वंशानुक्रम पदानुक्रम की 30 परतों के साथ एक वर्ग आरेख बहुत चुनौतीपूर्ण है।

यदि आपके API का उपयोग करने वाले लाखों डेवलपर हैं, या आपका कोड आधार वास्तव में बड़ा है (100K LOC से अधिक) तो उन दिशानिर्देशों का पालन करने से बहुत मदद मिल सकती है।

यदि 5 मिलियन डेवलपर 15 मिनट खर्च करने के बजाय एक एपीआई सीखने में 60 मिनट खर्च करते हैं, तो इसका परिणाम 428 मानव वर्षों की शुद्ध बचत है। वह बहुत समय है।

हालाँकि, अधिकांश परियोजनाओं में लाखों डेवलपर या 100K + LOC शामिल नहीं होते हैं। एक विशिष्ट परियोजना में, 4 डेवलपर्स और लगभग 50K लोको के साथ, मान्यताओं का सेट बहुत अलग है। टीम के डेवलपर्स को बेहतर समझ होगी कि कोड कैसे काम करता है। इसका मतलब है कि यह उच्च गुणवत्ता वाले कोड को जल्दी से बनाने के लिए अनुकूलन करने के लिए बहुत अधिक समझ में आता है, और बग की मात्रा को कम करने और परिवर्तन करने के लिए आवश्यक प्रयास के लिए।

1 सप्ताह का विकासशील कोड जो कि .net फ्रेमवर्क के अनुरूप है, बनाम 8 घंटे का कोड लिखना जो बदलना आसान है और जिसमें कम कीड़े हैं, में परिणाम हो सकते हैं:

  1. देर से परियोजनाओं
  2. कम बोनस
  3. बढ़ी हुई बग मायने रखता है
  4. अधिक समय कार्यालय में बिताया जाता है, और समुद्र तट पर कम समय मार्जरीस पीने से।

4,999,999 के बिना अन्य डेवलपर्स लागत को अवशोषित करने के लिए आमतौर पर इसके लायक नहीं है।

उदाहरण के लिए, मार्कर इंटरफेस के लिए परीक्षण एक एकल "अभिव्यक्ति" के लिए नीचे आता है, और कम कोड में परिणाम होता है जो विशेषताओं की तलाश में है।

तो मेरी सलाह है:

  1. यदि आप क्लास लाइब्रेरीज़ (या UI विजेट) विकसित कर रहे हैं, तो व्यापक रूप से खपत के लिए फ्रेमवर्क दिशा-निर्देशों का पालन करें।
  2. यदि आप अपनी परियोजना में 100K LOC से अधिक है, तो उनमें से कुछ को अपनाने पर विचार करें
  3. अन्यथा उन्हें पूरी तरह से नजरअंदाज करें।

12
मैं, व्यक्तिगत रूप से, किसी भी कोड को देखता हूं जिसे मैं एक पुस्तकालय के रूप में लिखता हूं जिसे मुझे बाद में उपयोग करना होगा। मुझे वास्तव में उपभोग की परवाह नहीं है या नहीं - निम्नलिखित दिशानिर्देशों से स्थिरता बढ़ती है, और आश्चर्य कम हो जाता है जब मुझे अपने कोड को देखने और इसे वर्षों बाद समझने की आवश्यकता होती है ...
रीड कोपसे

16
मैं यह नहीं कह रहा हूं कि दिशा-निर्देश खराब हैं। मैं कह रहा हूं कि उन्हें आपके कोड आधार के आकार और आपके उपयोगकर्ताओं की संख्या के आधार पर अलग-अलग होना चाहिए। बहुत सारे डिज़ाइन दिशा-निर्देश मेन्टिंग बाइनरी तुलनीयता जैसी चीज़ों पर आधारित हैं, जो "आंतरिक" पुस्तकालयों के लिए उतना ही महत्त्वपूर्ण नहीं है जितना कि प्रोजेक्ट की एक हैंडफुल द्वारा उपयोग की जाने वाली लाइब्रेरी जैसा कि यह बीसीएल की तरह ही है। प्रयोज्य से संबंधित अन्य दिशानिर्देश, हमेशा महत्वपूर्ण होते हैं। नैतिकता दिशानिर्देशों के बारे में अधिक धार्मिक नहीं होना है, खासकर छोटी परियोजनाओं पर।
स्कॉट Wisniewski

6
+1 - ओपी के सवाल का बहुत जवाब नहीं दिया - एमआई का उद्देश्य - लेकिन फिर भी बहुत उपयोगी है।
बजरह

5
@ScottWisniewski: मुझे लगता है कि आप गंभीर बिंदुओं को याद कर रहे हैं। फ्रेमवर्क दिशानिर्देश केवल बड़े प्रोजेक्ट पर लागू नहीं होते हैं, वे मध्यम और कुछ छोटे प्रोजेक्ट पर लागू होते हैं। जब आप हमेशा उन्हें हैलो-वर्ल्ड प्रोग्राम में लागू करने का प्रयास करते हैं, तो वे ओवर-किल हो जाते हैं। उदाहरण के लिए, 5 विधियों में इंटरफेस को सीमित करना ऐप-साइज़ की परवाह किए बिना हमेशा एक अच्छा नियम है। एक और बात जो आपको याद आती है, वह छोटा ऐप आज कल का बड़ा ऐप बन सकता है। इसलिए, बेहतर होगा कि आप इसे अच्छे सिद्धांतों के साथ बनाएँ जो कि बड़े ऐप को ध्यान में रखते हैं ताकि जब यह बड़े पैमाने पर हो जाए, तो आपको बहुत सारे कोड को फिर से लिखना न पड़े।
फिल

2
मैं यह नहीं देखता कि कैसे (अधिकांश) डिजाइन दिशानिर्देशों का पालन करते हुए 8 सप्ताह की परियोजना के परिणामस्वरूप अचानक 1 सप्ताह लगेगा। पूर्व: इसके बजाय एक virtual protectedटेम्पलेट विधि का नामकरण करना बहुत अतिरिक्त काम नहीं है और आप स्पष्ट रूप से संवाद करते हैं कि यह एक टेम्पलेट विधि है ... IMNSHO, जो लोग एपीआई पर विचार किए बिना आवेदन लिखते हैं ( ) बिल्कुल वही लोग हैं जो बहुत सारे नकल करते हैं ( और भी undocumented और आमतौर पर अपठनीय) कोड, चारों ओर अन्य तरीके से नहीं। DoSomethingCoreDoSomethingBut.. I'm not a framework developer, I don't care about my API!
लाउजिन

44

मार्कर इंटरफेस का उपयोग रन-टाइम में एक विशिष्ट इंटरफ़ेस को लागू करने के रूप में एक वर्ग की क्षमता को चिह्नित करने के लिए किया जाता है।

इंटरफेस डिजाइन और नेट प्रकार डिजाइन दिशानिर्देश - इंटरफेस डिजाइन सी # में विशेषताओं का उपयोग करने के पक्ष में मार्कर इंटरफेस के उपयोग को हतोत्साहित, लेकिन जैसा कि @Jay Bazuzi बताते हैं, यह विशेषताओं के लिए की तुलना में मार्कर इंटरफेस के लिए जाँच करने के लिए आसान है:o is I

तो इसके बजाय:

public interface IFooAssignable {} 

public class FooAssignableAttribute : IFooAssignable 
{
    ...
}

.NET दिशानिर्देशों ने सिफारिश की है कि आप ऐसा करते हैं:

public class FooAssignableAttribute : Attribute 
{
    ...
}

[FooAssignable]
public class Foo 
{    
   ...
} 

27
इसके अलावा, हम मार्कर इंटरफेस के साथ पूरी तरह से जेनरिक का उपयोग कर सकते हैं, लेकिन विशेषताओं के साथ नहीं।
जोर्डो

18
जबकि मुझे प्यार है और वे एक घोषणापत्र से कैसे दिखते हैं, वे रनटाइम के दौरान प्रथम श्रेणी के नागरिक नहीं हैं और उनके साथ काम करने के लिए अपेक्षाकृत कम स्तर की पाइपलाइन की महत्वपूर्ण मात्रा की आवश्यकता होती है।
जेसी सी। स्लीकर

4
@ जोर्डो - यह मेरा विचार बिल्कुल था। एक उदाहरण के रूप में, यदि मैं डेटाबेस एक्सेस कोड (लिनक को Sql कहता हूं) को सार करना चाहता हूं, तो एक सामान्य इंटरफ़ेस होने से यह एओटी आसान हो जाता है। वास्तव में, मुझे नहीं लगता कि विशेषताओं के साथ उस तरह का अमूर्त लिखना संभव होगा क्योंकि आप किसी विशेषता को नहीं डाल सकते हैं और जेनरिक में उनका उपयोग नहीं कर सकते हैं। मुझे लगता है कि आप एक खाली आधार वर्ग का उपयोग कर सकते हैं जिसमें से अन्य कक्षाएं सभी प्राप्त होती हैं, लेकिन वह खाली इंटरफ़ेस के समान ही महसूस करता है। इसके अलावा, अगर आपको बाद में पता चलता है कि आपको साझा कार्यक्षमता की आवश्यकता है, तो तंत्र पहले से ही मौजूद है।
tandrewnichols

23

चूंकि हर दूसरे जवाब में कहा गया है कि "उन्हें टाला जाना चाहिए", इसलिए इसका स्पष्टीकरण देना उपयोगी होगा।

सबसे पहले, मार्कर इंटरफेस का उपयोग क्यों किया जाता है: वे उस कोड की अनुमति देने के लिए मौजूद हैं जो उस ऑब्जेक्ट का उपयोग कर रहा है जो यह जांचने के लिए लागू करता है कि क्या वे उक्त इंटरफ़ेस को लागू करते हैं और ऑब्जेक्ट को अलग तरीके से मानते हैं।

इस दृष्टिकोण के साथ समस्या यह है कि यह एनकैप्सुलेशन को तोड़ता है। वस्तु का अब खुद पर अप्रत्यक्ष नियंत्रण है कि इसे बाहरी रूप से कैसे उपयोग किया जाएगा। इसके अलावा, इसे उस प्रणाली का ज्ञान है जिसका उपयोग करने जा रहा है। मार्कर इंटरफ़ेस को लागू करने से, वर्ग परिभाषा यह सुझाव दे रही है कि इसका उपयोग कहीं न कहीं होने की उम्मीद है जो मार्कर के अस्तित्व की जांच करता है। इसमें उपयोग किए गए वातावरण का निहित ज्ञान है और यह परिभाषित करने की कोशिश कर रहा है कि इसका उपयोग कैसे किया जाना चाहिए। यह एनकैप्सुलेशन के विचार के खिलाफ जाता है क्योंकि इसमें सिस्टम के एक हिस्से के कार्यान्वयन का ज्ञान है जो पूरी तरह से अपने दायरे से बाहर मौजूद है।

व्यावहारिक स्तर पर यह पोर्टेबिलिटी और पुन: प्रयोज्य को कम करता है। यदि क्लास को एक अलग एप्लिकेशन में फिर से उपयोग किया जाता है, तो इंटरफ़ेस को भी कॉपी करने की आवश्यकता होती है, और नए वातावरण में इसका कोई अर्थ नहीं हो सकता है, जिससे यह पूरी तरह से निरर्थक हो जाता है।

जैसे, "मार्कर" वर्ग के बारे में मेटाडेटा है। इस मेटाडेटा का उपयोग केवल कक्षा द्वारा ही नहीं किया जाता है और यह केवल (कुछ!) बाहरी क्लाइंट कोड के लिए सार्थक होता है ताकि यह एक निश्चित तरीके से वस्तु का इलाज कर सके। क्योंकि इसका केवल क्लाइंट कोड से मतलब है, मेटाडेटा क्लाइंट कोड में होना चाहिए, न कि क्लास एपीआई के लिए।

"मार्कर इंटरफ़ेस" और सामान्य इंटरफ़ेस के बीच का अंतर यह है कि विधियों वाला एक इंटरफ़ेस बाहरी दुनिया को बताता है कि इसका उपयोग कैसे किया जा सकता है जबकि एक खाली इंटरफ़ेस का अर्थ है कि यह बाहरी दुनिया को बता रहा है कि इसका उपयोग कैसे किया जाना चाहिए।


1
किसी भी इंटरफ़ेस का प्राथमिक उद्देश्य उन वर्गों के बीच अंतर करना है जो उस इंटरफ़ेस से जुड़े अनुबंध का पालन करने का वादा करते हैं, और जो नहीं करते हैं। जबकि एक इंटरफ़ेस अनुबंध को पूरा करने के लिए आवश्यक किसी भी सदस्य के कॉलिंग हस्ताक्षर की आपूर्ति के लिए भी जिम्मेदार है, यह अनुबंध है, सदस्यों के बजाय, जो निर्धारित करता है कि क्या किसी विशेष वर्ग द्वारा एक विशेष इंटरफ़ेस लागू किया जाना चाहिए। यदि अनुबंध IConstructableFromString<T>निर्दिष्ट करता है कि एक वर्ग Tकेवल तभी लागू कर सकता है IConstructableFromString<T>जब उसके पास एक स्थिर सदस्य हो ...
सुपरकैट

... public static T ProduceFromString(String params);, इंटरफ़ेस के लिए एक साथी वर्ग एक विधि की पेशकश कर सकता है public static T ProduceFromString<T>(String params) where T:IConstructableFromString<T>; यदि क्लाइंट कोड में एक विधि होती है T[] MakeManyThings<T>() where T:IConstructableFromString<T>, तो कोई भी नए प्रकार को परिभाषित कर सकता है जो क्लाइंट कोड के साथ काम कर सकता है ताकि उनसे निपटने के लिए क्लाइंट कोड को संशोधित किया जा सके। यदि मेटाडेटा क्लाइंट कोड में था, तो मौजूदा क्लाइंट द्वारा उपयोग के लिए नए प्रकार बनाना संभव नहीं होगा।
सुपरकैट

लेकिन इसका Tउपयोग करने वाले वर्ग के बीच का अनुबंध वह होता है IConstructableFromString<T>जहां आपके पास इंटरफ़ेस में एक विधि होती है जो कुछ व्यवहार का वर्णन करती है इसलिए यह एक मार्कर इंटरफ़ेस नहीं है।
टॉम बी

कक्षा के लिए आवश्यक स्थिर विधि इंटरफ़ेस का हिस्सा नहीं है। इंटरफेस में स्थैतिक सदस्यों को स्वयं इंटरफेस द्वारा कार्यान्वित किया जाता है; एक कार्यान्वयन वर्ग में एक स्थिर सदस्य को संदर्भित करने के लिए इंटरफ़ेस के लिए कोई रास्ता नहीं है।
सुपरकैट

यह प्रतिबिंबित करने के लिए एक विधि के लिए संभव है, परावर्तन का उपयोग करते हुए, चाहे एक सामान्य प्रकार एक विशेष स्थिर विधि हो, और उस विधि को निष्पादित करें यदि यह मौजूद है, लेकिन ProduceFromStringउपरोक्त उदाहरण में स्थैतिक विधि को खोजने और निष्पादित करने की वास्तविक प्रक्रिया शामिल नहीं होगी। किसी भी तरह से इंटरफ़ेस, सिवाय इसके कि इंटरफ़ेस का उपयोग मार्कर के रूप में किया जाएगा ताकि यह इंगित किया जा सके कि आवश्यक फ़ंक्शन को लागू करने के लिए किन वर्गों से अपेक्षा की जानी चाहिए।
सुपरकैट

8

मार्कर इंटरफेस कभी-कभी एक आवश्यक बुराई हो सकता है जब कोई भाषा भेदभावपूर्ण संघ प्रकारों का समर्थन नहीं करती है ।

मान लीजिए कि आप एक ऐसी विधि को परिभाषित करना चाहते हैं जो एक तर्क की अपेक्षा करता है जिसका प्रकार ए, बी, या सी में से एक होना चाहिए। कई कार्यात्मक-प्रथम भाषाओं (जैसे एफ # ) में, इस प्रकार को स्पष्ट रूप से परिभाषित किया जा सकता है:

type Arg = 
    | AArg of A 
    | BArg of B 
    | CArg of C

हालाँकि, O # पहली भाषाओं में जैसे C #, यह संभव नहीं है। यहां कुछ समान हासिल करने का एकमात्र तरीका इंटरफ़ेस आईएआरजी और इसके साथ "मार्क" ए, बी और सी को परिभाषित करना है।

बेशक, आप "इंटरफ़ेस" को तर्क के रूप में स्वीकार करके मार्कर इंटरफ़ेस का उपयोग करने से बच सकते हैं, लेकिन तब आप स्पष्टता और कुछ प्रकार की सुरक्षा खो देंगे।

विभेदित संघ प्रकार अत्यंत उपयोगी हैं और कम से कम 30 वर्षों से कार्यात्मक भाषाओं में मौजूद हैं। अजीब बात है, आज तक, सभी मुख्यधारा की ओओ भाषाओं ने इस सुविधा की अनदेखी की है - हालांकि इसका वास्तव में प्रति कार्यात्मक कार्यात्मक प्रोग्रामिंग से कोई लेना-देना नहीं है, लेकिन यह प्रकार प्रणाली से संबंधित है।


यह ध्यान देने योग्य है कि क्योंकि Foo<T>प्रत्येक प्रकार के लिए स्थैतिक फ़ील्ड का एक अलग सेट होगा T, एक जेनेरिक वर्ग के लिए कठिन नहीं होता है जिसमें स्थिर फ़ील्ड होते हैं जिनमें प्रतिनिधि प्रक्रिया करने के लिए प्रतिनिधि होते हैं T, और उन फ़ील्ड्स को प्री-पॉप्युलेट करते हैं जो हर प्रकार के वर्ग को संभालने के लिए कार्य करते हैं के साथ काम करना चाहिए प्रकार पर एक सामान्य इंटरफ़ेस बाधा का उपयोग करना Tसंकलक समय पर जांच करेगा कि आपूर्ति प्रकार कम से कम वैध होने का दावा करता है, भले ही यह सुनिश्चित करने में सक्षम नहीं होगा कि यह वास्तव में था।
सुपरकैट

6

एक मार्कर इंटरफ़ेस सिर्फ एक इंटरफ़ेस है जो खाली है। एक वर्ग इस इंटरफ़ेस को किसी कारण से उपयोग किए जाने वाले मेटाडेटा के रूप में लागू करेगा। C # में आप आमतौर पर उन विशेषताओं के लिए एक वर्ग को चिह्नित करने के लिए विशेषताओं का उपयोग करेंगे जिनके लिए आप अन्य भाषाओं में एक मार्कर इंटरफ़ेस का उपयोग करेंगे।


4

एक मार्कर इंटरफ़ेस एक वर्ग को इस तरह से टैग करने की अनुमति देता है जो सभी वंशजों पर लागू होगा। एक "शुद्ध" मार्कर इंटरफ़ेस कुछ भी परिभाषित या विरासत में नहीं मिलेगा; एक और उपयोगी प्रकार के मार्कर इंटरफेस एक हो सकते हैं जो एक और इंटरफ़ेस "विरासत में मिला" लेकिन कोई नया सदस्य परिभाषित नहीं करता है। उदाहरण के लिए, यदि कोई इंटरफ़ेस "IReadableFoo" है, तो एक इंटरफ़ेस "IImmutableFoo" को भी परिभाषित कर सकता है, जो "Foo" की तरह व्यवहार करेगा, लेकिन जो कोई भी इसका उपयोग करता है, उससे वादा करेगा कि इसका मूल्य नहीं बदलेगा। एक दिनचर्या जो एक IImmutableFoo को स्वीकार करती है वह इसे IReadableFoo के रूप में उपयोग करने में सक्षम होगी, लेकिन दिनचर्या केवल उन वर्गों को स्वीकार करेगी जिन्हें IImmutableFoo लागू करने के रूप में घोषित किया गया था।

मैं "शुद्ध" मार्कर इंटरफेस के लिए बहुत सारे उपयोगों के बारे में नहीं सोच सकता। केवल एक ही मैं सोच सकता हूं कि यदि EqualityComparer (T का) .Default Object.Equals को किसी भी प्रकार के लिए लौटाएगा, जिसने IDoNotUseEqualityComparer को लागू किया है, भले ही वह प्रकार IEquotComparer लागू हो। यह Liskov प्रतिस्थापन सिद्धांत का उल्लंघन किए बिना एक अपरिवर्तनीय अपरिवर्तनीय प्रकार की अनुमति देगा: यदि यह प्रकार समानता-परीक्षण से संबंधित सभी तरीकों को सील करता है, तो एक व्युत्पन्न प्रकार अतिरिक्त फ़ील्ड जोड़ सकता है और उन्हें उत्परिवर्तित कर सकता है, लेकिन ऐसे फ़ील्ड का उत्परिवर्तन नहीं होगा ' किसी भी आधार-प्रकार के तरीकों का उपयोग करके दृश्यमान नहीं होना चाहिए। एक असुरक्षित अपरिवर्तनीय वर्ग के लिए यह भयानक नहीं हो सकता है और या तो EqualityComparer.Default या विश्वास प्राप्त वर्गों के किसी भी उपयोग से बचना चाहिए ताकि IEqualityComparer को लागू न किया जा सके,


4

ये दो विस्तार विधियां अधिकांश मुद्दों को हल करेंगी स्कॉट विशेषताओं पर पक्ष-विपक्ष इंटरफेस का दावा करते हैं:

public static bool HasAttribute<T>(this ICustomAttributeProvider self)
    where T : Attribute
{
    return self.GetCustomAttributes(true).Any(o => o is T);
}

public static bool HasAttribute<T>(this object self)
    where T : Attribute
{
    return self != null && self.GetType().HasAttribute<T>()
}

अब आपके पास है:

if (o.HasAttribute<FooAssignableAttribute>())
{
    //...
}

बनाम:

if (o is IFooAssignable)
{
    //...
}

मैं यह देखने में विफल रहा कि एक एपीआई का निर्माण स्कॉट के दावों की तुलना में दूसरे की तुलना में पहले पैटर्न के साथ 5 गुना लंबा होगा।


1
फिर भी कोई जेनरिक नहीं।
इयान केम्प

0

मार्कर खाली इंटरफेस हैं। एक मार्कर या तो वहाँ है या यह नहीं है।

कक्षा फू: IConfidential

यहां हम फू को गोपनीय बताते हैं। कोई वास्तविक अतिरिक्त गुण या विशेषता की आवश्यकता नहीं है।


0

मार्कर इंटरफ़ेस कुल रिक्त इंटरफ़ेस है जिसका कोई निकाय / डेटा-सदस्य / कार्यान्वयन नहीं है। जब आवश्यकता होती है
एक वर्ग मार्कर इंटरफ़ेस लागू करता है, यह सिर्फ " निशान " करने के लिए है; इसका अर्थ है कि यह जेवीएम को बताता है कि विशेष वर्ग क्लोनिंग के उद्देश्य से है इसलिए इसे क्लोन करने की अनुमति दें। यह विशेष वर्ग अपनी वस्तुओं को क्रमबद्ध करने के लिए है, इसलिए कृपया अपनी वस्तुओं को क्रमबद्ध करने की अनुमति दें।


0

मार्कर इंटरफ़ेस वास्तव में OO भाषा में केवल एक प्रक्रियात्मक प्रोग्रामिंग है। एक इंटरफ़ेस एक मार्कर इंटरफ़ेस को छोड़कर, कार्यान्वयनकर्ताओं और उपभोक्ताओं के बीच एक अनुबंध को परिभाषित करता है, क्योंकि एक मार्कर इंटरफ़ेस कुछ भी नहीं बल्कि खुद को परिभाषित करता है। इसलिए, गेट के ठीक बाहर, मार्कर इंटरफ़ेस एक इंटरफ़ेस होने के मूल उद्देश्य में विफल रहता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.