2012-02-28 19 views
6

के लिए .NET में संपत्ति के रूप में एक्सपोज़िंग करना। मैं .NET में एक रैपर क्लास बना रहा हूं (वीबीएनईटी जैसा होता है लेकिन यह समान रूप से सी # से संबंधित है) जो COM के संपर्क में आता है और उन गुणों में से एक जो मैं लपेटने की कोशिश कर रहा हूं एक संस्करण है। मैंने सोचा कि मैं सिर्फ एक वस्तु का उपयोग करने में सक्षम हो जाएगा, लेकिन मैं कोई त्रुटि मिलती है:इंटरपॉप

Public Property FieldValue([vFieldID As Object = -1]) As Object cannot be exposed to COM as a property 'Let'. You will not be able to assign non-object values (such as numbers or strings) to this property from Visual Basic 6.0 using a 'Let' statement.*

मेरी संपत्ति घोषणा इस तरह दिखता है:

Public Property FieldValue(Optional ByVal vFieldID As Object = -1) As Object 
    Get 
     Return _objVAccess.FieldValue(vFieldID) 
    End Get 
    Set(ByVal value As Object) 
     _objVAccess.FieldValue = value 
    End Set 
End Property 

मेरी संपत्ति वास्तव में डेटाबेस से एक मान देता है जो कर सकते हैं पूर्णांक, स्ट्रिंग, दिनांक इत्यादि बनें ताकि COM के संदर्भ में कोई ऑब्जेक्ट न हो। संपत्ति को अनुमति देने के लिए क्या कोई कामकाज है?

+0

क्या आपने 'ऑब्जेक्ट' के बजाय 'ValueType' का उपयोग करने का प्रयास किया है? –

+0

एमएसडीएन वर्णन करता है कि इसे एक स्ट्रक्चर के साथ कैसे किया जाए, लेकिन मैं इसे पूरी तरह से अपने आप नहीं मानता: http://msdn.microsoft.com/en-us/library/2x07fbw8(v=vs.71).aspx –

+0

किसी भी तरह से संबंधित: http://stackoverflow.com/q/26385964/2140173 –

उत्तर

28

COM ऑटोमेशन एक डिफ़ॉल्ट संपत्ति का समर्थन करता है, संपत्ति जिसमें विवाद 0 है। इसका उपयोग वीबी 6 कोड में बहुत प्रभाव से किया जाता है, वास्तव में कॉम्पैक्ट कोड उत्पन्न करता है। एक विशिष्ट उदाहरण है:

rs!Customer = "foo" 

कौन सा वाक्य रचना चीनी है के लिए:

rs.Fields.Item("Customer").Value = "foo" 

तीन डिफ़ॉल्ट गुण यहाँ मूल बयान में नामित होने के बिना इस्तेमाल किया जा रहा। रिकॉर्ड्स इंटरफ़ेस में फ़ील्ड्स प्रॉपर्टी को डिफ़ॉल्ट संपत्ति के रूप में फ़ील्ड इंटरफ़ेस संदर्भ का उत्पादन होता है। फ़ील्ड इंटरफ़ेस संदर्भ का उत्पादन करने वाली डिफ़ॉल्ट (अनुक्रमित) संपत्ति के रूप में आइटम प्रॉपर्टी कौन सा है। वैल्यू प्रॉपर्टी को डिफॉल्ट प्रॉपर्टी के रूप में एक वैरिएंट का उत्पादन होता है।

जो बहुत अच्छा है। हालांकि इस तरह चरम वाक्यविन्यास चीनी की कीमत दांत क्षय है। एक बयान में एक वाक्यविन्यास अस्पष्टता है:

Dim obj 
obj = someObject 

यहां क्या उद्देश्य है? क्या आप obj को कुछ ऑब्जेक्ट संदर्भ असाइन करना चाहते हैं? या आप कुछ ऑब्जेक्ट के डिफ़ॉल्ट संपत्ति असाइन करना चाहते हैं? बहुत अलग चीजें, obj प्रकार पूरी तरह से अलग होगा। यह कीवर्ड के साथ वीबी 6 में हल किया गया था। आप तो ऑब्जेक्ट संदर्भ प्रदान करना चाहते हैं आप लिखने के लिए है:

Set obj = someObject 

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

COM ऑटोमेशन एक संपत्ति को दो सेटर्स रखने की अनुमति देकर इसे लागू करता है।आदरणीय प्रोपूट और आईडीपीएल में propputref जहां propputref वह ऑब्जेक्ट निर्दिष्ट करता है। आप इसे IDISpatch परिभाषा में भी देख सकते हैं, IDISpatch :: Invoke() विधि DISPATCH_PROPERTYPUT और DISPATCH_PROPERTYPUTREF के साथ दोनों के बीच अंतर करती है।

वीबीएनईटी को आगे बढ़ें, माइक्रोसॉफ्ट ने फैसला किया कि अस्पष्टता बहुत दर्दनाक थी और एक डिफ़ॉल्ट गैर अनुक्रमित संपत्ति की धारणा को समाप्त कर दिया था। जिसने सेट कीवर्ड को भी खुशी से सेवानिवृत्त किया। हालांकि यह एक नई समस्या पैदा करता है, अब [कॉमविज़िबल] कक्षा लिखने का कोई तरीका नहीं है जिसमें किसी ऑब्जेक्ट संदर्भ को स्वीकार करने वाले सेटर के साथ ऑब्जेक्ट प्रकार की संपत्ति हो सकती है। भाषा वाक्यविन्यास केवल एक सेटटर परमिट करता है और सीएलआर में COM इंटरऑप परत दो को संश्लेषित करने के लिए नलसाजी गुम है। उल्लेखनीय यह है कि यह सिर्फ एक चेतावनी है, आपको अभी भी प्रोपूट सेटटर मिल गया है, आपको बस प्रोपूट्रफ़ सेटटर नहीं मिलेगा। जहां तक ​​मैं कह सकता हूं वह वही है जो आप चाहते हैं।

या तो वीबी 6 डमी क्लास में इंटरफ़ेस को परिभाषित करना या आईडीएल को स्पष्ट रूप से लिखना और midl.exe के साथ इसे संकलित करना वास्तव में चेतावनी के चारों ओर जाने का एक तरीका है। जैसा कि जॉन रिवार्ड द्वारा this question में दिखाया गया है।

+0

अंत में मैं देखता हूं कि एसईटी/एलईटी वास्तव में कैसे काम करता है और क्यों। बहुत धन्यवाद। – quetzalcoatl

+0

यह। अंततः मेरा सिरदर्द इस स्पष्टीकरण के साथ चला गया है। – Scorchio

+0

तो DISPATCH_PROPERTYPUT, सीधे संपत्ति को सेट करने के बजाय, संपत्ति द्वारा संदर्भित ऑब्जेक्ट की डिफ़ॉल्ट संपत्ति सेट करेगा? – Medinoc

2

क्या आपने MarshalAs विशेषता का उपयोग करने का प्रयास किया था?

Public Property FieldValue(Optional ByVal vFieldID As Object = -1) As <MarshalAsAttribute(UnmanagedType.Struct)> Object 
    Get 
     Return _objVAccess.FieldValue(vFieldID) 
    End Get 
    Set(ByVal value As Object) 
     _objVAccess.FieldValue = value 
    End Set 
End Property 

यह एक VARIANT संरचना के रूप में संपत्ति का पर्दाफाश करने के marshaller बताना चाहिए:

आपको लगता है कि जैसे कि यह लागू करने के लिए सक्षम होना चाहिए (खेद अगर मैं एक वाक्य रचना गलती है, मैं आमतौर पर सी # का उपयोग करें)।

आपको संरचना आकार आदि के लिए अतिरिक्त विशेषताओं को लागू करना पड़ सकता है, लेकिन मुझे लगता है कि यह वह दिशा है जिसका उपयोग आप अपनी समस्या को हल करने के लिए कर सकते हैं।

+0

मुझे विजुअल स्टूडियो में एक ही चेतावनी मिलती है और मैं वीबी 6 –

+0

में संपत्ति को नहीं लिख सकता, मैंने इसे संबंधित समस्या के लिए उपयोग किया, 64 बिट पूर्णांक को उजागर किया COM के माध्यम से एक वीबी 6 आवेदन। यहां वाक्यविन्यास है: संपत्ति का आकार() <मार्शलएएस (UnmanagedType.Struct)> ऑब्जेक्ट –