2009-05-17 10 views
20

मेरे पास एक लिंक क्वेरी द्वारा आबादी वाला डाटाग्रिड है। जब डेटाग्रिड में केंद्रित पंक्ति में परिवर्तन होता है तो मुझे उस ऑब्जेक्ट में गुणों में से किसी एक के बराबर एक चर सेट करने की आवश्यकता होती है।मुझे किसी अज्ञात प्रकार से किसी संपत्ति का मूल्य कैसे प्राप्त हो सकता है?

मैंने कोशिश की ...

var selectedObject = view.GetRow(rowHandle); 
_selectedId = selectedObject.Id; 

... लेकिन संकलक सब पर इस की परवाह नहीं करता ("एंबेडेड बयान एक घोषणा या लेबल बयान नहीं किया जा सकता")।

ऐसा लगता है कि संपत्ति का उपयोग करना आसान होना चाहिए। रनटाइम के दौरान ऑब्जेक्ट का निरीक्षण करने से मैं उन सभी गुणों को दिखाता हूं जो मुझे उम्मीद है, मुझे नहीं पता कि उन्हें कैसे पहुंचाया जाए।

मैं अज्ञात ऑब्जेक्ट की संपत्ति तक कैसे पहुंच सकता हूं? स्पष्टीकरण के लिए

संपादित करें:

मैं हो DevExpress XtraGrid नियंत्रण का उपयोग किया जाना है। मैंने इस नियंत्रण को एक लिंक क्वेरी के साथ लोड किया जो कई अलग-अलग ऑब्जेक्ट्स से बना था, इसलिए डेटा को वास्तव में किसी एक वर्ग के अनुरूप नहीं बना रहा है (यानी, मैं इसे किसी भी चीज़ पर नहीं डाल सकता)।

मैं .NET 3.5 का उपयोग कर रहा हूं।

जब मैं view.GetRow (rowHandle) विधि के परिणाम को देखने मैं एक गुमनाम प्रकार है कि इस तरह दिखता है मिलती है:

{ ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 } 

मेरे उद्देश्य इस अनाम प्रकार से clientid पाने के लिए तो मैं क्या कर सकता है अन्य चीजें (जैसे कि इसमें उस क्लाइंट रिकॉर्ड के साथ एक फॉर्म लोड करें)।

मैंने शुरुआती उत्तरों में कुछ सुझावों की कोशिश की लेकिन वह उस बिंदु तक पहुंचने में असमर्थ था जहां मैं इस क्लाइंट आईडी प्राप्त कर सकता था।

+0

पहचानकर्ता "व्यू" का सटीक प्रकार क्या है? – AnthonyWJones

+0

"व्यू" DevExpress से ग्रिड व्यू नियंत्रण है। –

उत्तर

43

क्या आपने कभी प्रतिबिंब का उपयोग करने की कोशिश की है?

// use reflection to retrieve the values of the following anonymous type 
var obj = new { ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }; 
System.Type type = obj.GetType(); 
int clientid = (int)type.GetProperty("ClientId").GetValue(obj, null); 
string clientname = (string)type.GetProperty("ClientName").GetValue(obj, null); 

// use the retrieved values for whatever you want... 
+0

धन्यवाद abdoul, आपका कोड समझने के लिए बहुत आसान है। मुझे हाल ही में अज्ञात प्रकार और यहां प्राप्त करने में समस्या आई थी: http: //stackoverflow.com/questions/3534969/only-parameterless-constructors-and-initializers-are-supported-in-linq-to-entitie मैंने प्रश्न छोड़ा। सप्ताहांत पर कुछ खोज और काम करने के बाद मैं इस पृष्ठ पर आया और यह वास्तव में मेरा दिन बना। – Developer

+0

यही कारण है कि मुझे SO – Bergkamp

+0

वास्तव में बहुत अच्छा जवाब पसंद है! यही वह है जो मैं 2 सप्ताह से खोज रहा था! बहुत धन्यवाद! – KomalJariwala

17

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

मैं बिल्कुल नहीं बता सकता कि आप किस एपीआई का उपयोग कर रहे हैं। हालांकि एपीआई के लिए दृढ़ता से टाइप किए गए अनाम प्रकार को वापस करना संभव नहीं है, इसलिए उस चयनित ऑब्जेक्ट में मेरा अनुमान ऑब्जेक्ट पर टाइप किया गया है। सी # 3.0 और नीचे गतिशील पहुंच का समर्थन नहीं करता है, इसलिए यदि आप रनटाइम पर उपलब्ध हैं तो भी आप संपत्ति आईडी तक पहुंचने में असमर्थ होंगे।

आप में से एक की आवश्यकता होगी संपत्ति

  • एक पूर्ण प्रकार बनाएं हड़पने के लिए इस

    • उपयोग प्रतिबिंब के आसपास मिलता है और उपयोग करने वाले datagrid
    • कई का प्रयोग एक पॉप्युलेट करने के लिए के लिए निम्न hacky गुमनाम प्रकार डाले

    संपादित

    यहाँ कारण यह hacky है कि यह इस तोड़ने के लिए बहुत आसान है है डाली

    public T AnonymousTypeCast<T>(object anonymous, T typeExpression) { 
        return (T)anonymous; 
    } 
    
    ... 
    object obj = GetSomeAnonymousType(); 
    var at = AnonymousTypeCast(obj, new { Name = String.Empty, Id = 0 }); 
    

    कैसे हैक गुमनाम प्रकार करने के लिए पर एक नमूना है। उदाहरण के लिए विधि में जहां अज्ञात प्रकार मूल रूप से बनाया गया है। यदि मैं टाइप में एक और प्रॉपर्टी जोड़ता हूं तो ऊपर दिया गया कोड संकलित होगा लेकिन रनटाइम पर असफल होगा।

  • +0

    "हैकी अज्ञात प्रकार कास्ट" उन क्या हैं? – AnthonyWJones

    +0

    @ एंथनीWJones, मैंने एक हैकी अज्ञात प्रकार का कास्ट जोड़ा – JaredPar

    +0

    इस उत्तर के लिए धन्यवाद। एक बहुत अच्छा और सुरुचिपूर्ण समाधान। इसमें केवल एक ही दोष है: यदि अज्ञात ऑब्जेक्ट किसी अन्य असेंबली से आता है तो यह काम नहीं करता है। यह एक कारण है कि आपको कभी भी एक विधि से किसी अज्ञात ऑब्जेक्ट को वापस नहीं करना चाहिए, लेकिन सभी को यह नहीं पता है और इसलिए मुझे एक पुस्तकालय से निपटना है जो दुर्भाग्यवश वास्तव में करता है। –

    0

    यह गलत हो सकता है (आपके पास पर्याप्त कोड नहीं हो सकता है) लेकिन आपको पंक्ति में अनुक्रमित करने की आवश्यकता नहीं है ताकि आप चुन सकें कि आप कौन सा कॉलम चाहते हैं? या अगर "आईडी" कॉलम आप चाहते है, तो आप कुछ इस तरह करना चाहिए:

    var selectedObject = view.GetRow(rowHandle); 
    _selectedId = selectedObject["Id"]; 
    

    यह कैसे मैं एक datagrid में एक स्तंभ की सामग्री हड़पने चाहते हैं। अब यदि कॉलम स्वयं एक अनाम प्रकार है, तो मुझे पता नहीं है, लेकिन अगर आपको एक आदिम प्रकार के साथ नामित कॉलम मिल रहा है, तो यह काम करना चाहिए।

    1

    जैसा कि जेरेडपार सही ढंग से अनुमान लगाया गया है, GetRow() का वापसी प्रकार object है।

    int clientId = (int)gridView.GetRowCellValue(rowHandle, "ClientId"); 
    

    यह दृष्टिकोण की तरह समान कमियां "hacky गुमनाम प्रकार डाले" में वर्णित किया है से पहले:: जब DevExpress ग्रिड के साथ काम करने के लिए, आप इस तरह वांछित मान एक्सट्रैक्ट सकता है आप स्तंभ की पहचान के लिए एक जादू स्ट्रिंग की जरूरत के साथ साथ एक वस्तु से int तक कास्ट टाइप करें।

    2

    जब मैं गुमनाम प्रकारों के चारों ओर गुजरने के साथ काम कर रहा था और उन्हें पुन: प्रयास करने की कोशिश कर रहा था तो मुझे अंततः ऑब्जेक्ट के साथ काम करने वाले एक रैपर को लिखना आसान हो गया। यहां इसके बारे में एक ब्लॉग पोस्ट का एक लिंक है।

    http://somewebguy.wordpress.com/2009/05/29/anonymous-types-round-two/

    अंत में, अपने कोड कुछ इस तरह दिखेगा।

    //create an anonymous type 
    var something = new { 
        name = "Mark", 
        age = 50 
    }; 
    AnonymousType type = new AnonymousType(something); 
    
    //then access values by their property name and type 
    type.With((string name, int age) => { 
        Console.Write("{0} :: {1}", name, age); 
    }); 
    
    //or just single values 
    int value = type.Get<int>("age"); 
    
    0

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

    private List<StockSymbolResult> GetDistinctSymbolList(List<ICommonFields> l) 
          { 
           var DistinctList = (
             from a 
             in l 
             orderby a.Symbol 
             select new 
             { 
              a.Symbol, 
              a.StockID 
             }).Distinct(); 
    
           StockSymbolResult ssr; 
           List<StockSymbolResult> rl = new List<StockSymbolResult>(); 
           foreach (var i in DistinctList) 
           { 
               // Symbol is a string and StockID is an int. 
            ssr = new StockSymbolResult(i.Symbol, i.StockID); 
            rl.Add(ssr); 
           } 
    
           return rl; 
          } 
    
    17

    किसी कुंजी के

    public static T GetValueFromAnonymousType<T>(object dataitem, string itemkey) { 
        System.Type type = dataitem.GetType(); 
        T itemvalue = (T)type.GetProperty(itemkey).GetValue(dataitem, null); 
        return itemvalue; 
    } 
    

    उदाहरण के लिए एक डेटा आइटम के मूल्य प्राप्त करने के लिए एक सामान्य समाधान:

    var dataitem = /* Some value here */; 
    bool ismember = TypeUtils.GetValueFromAnonymousType<bool>(dataitem, "IsMember"); 
    
    +0

    मुझे यह समाधान अज्ञात प्रकारों को घोषित करने के लिए अगली सबसे अच्छा पाया गया। धन्यवाद। – DoomerDGR8

    0

    आप कर सकते हैं इस तरह एक गुमनाम प्रकार के गुणों के माध्यम से लूप :

    var obj = new {someValue = "hello", otherValue = "world"}; 
    foreach (var propertyInfo in obj.GetType().GetProperties() { 
        var name = propertyInfo.Name; 
        var value = propertyInfo.GetValue(obj, index: null); 
        ... 
    } 
    
    0

    DevExpre एसएस के xtraGridView में इस तरह की एक विधि है GetRowCellDisplayText (int rowHandle, GridColumn कॉलम)। इस विधि के साथ, निम्न कोड आईडी को अनाम प्रकार से वापस कर देता है।

    var _selectedId = view.GetRowCellDisplayText(rowHandle, "Id"); 
    

    हालांकि इस प्रश्न का उत्तर प्रदान नहीं करता है "मैं गुमनाम वस्तु की संपत्ति पर कैसे पहुँच सकते हैं?", यह अभी भी समस्या के मूल कारण को हल करने के प्रयास करता है।

    मैंने इसे devXpress संस्करण 11.1 के साथ करने की कोशिश की और मैं देख सकता हूं कि सवाल लगभग 2.5 साल पहले पूछा गया था। शायद इस सवाल के लेखक को एक समाधान मिल गया हो या समाधान स्वयं पाया हो। फिर भी, मैं अभी भी जवाब दे रहा हूं ताकि यह किसी की मदद कर सके।

    11

    आप प्रतिबिंब का उपयोग किए बिना रनटाइम पर गुमनाम प्रकारों के गुणों तक पहुंचने के लिए गतिशील प्रकार का उपयोग कर सकते हैं।

    var aType = new { id = 1, name = "Hello World!" }; 
    //... 
    //... 
    dynamic x = aType; 
    Console.WriteLine(x.name); // Produces: Hello World! 
    

    गतिशील प्रकार के बारे में यहाँ और अधिक पढ़ें: http://msdn.microsoft.com/en-us/library/dd264736.aspx

    +0

    इतना आसान और सुरुचिपूर्ण मुझे इसके बारे में सोचने में शर्म आती है :) – percebus

    0

    आप जानते हैं कि आप क्या कर रहे हैं और जब आपके कोड में परिवर्तन, आप dynamic के रूप में अपने पंक्ति डेटा डाली सकता है क्रम त्रुटियों होने का डर नहीं कर रहे हैं:

    var data = view.GetRow(rowHandle) as dynamic; 
    
    int clientId  = data.ClientID; 
    string clientName = data.ClientName; 
    int jobs   = data.Jobs 
    

    कोई संकलन-समय सत्यापन नहीं। लेकिन यह अच्छी तरह से काम करना चाहिए।

    0
    var result = ((dynamic)DataGridView.Rows[rowNum].DataBoundItem).value; 
    
    +0

    यह सूची के गुणों (डेटाग्रिड व्यू) के मूल्य को प्राप्त करने के लिए सबसे आसान फोमरा है –

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