ऑब्जेक्ट को उसके वास्तविक प्रकार में कैसे डालें?


120

अगर मेरे पास:

void MyMethod(Object obj) {   ...   }

मैं कैसे कर सकता हूँ objकि इसका वास्तविक प्रकार क्या है?


2
क्या संकलन समय पर ज्ञात है?
Psubsee2003

1
और आप इससे क्या हासिल करने की उम्मीद करते हैं? कृपया हमें बताएं कि आप क्या हासिल करने की कोशिश कर रहे हैं, बजाय इसके कि आप इसे कैसे हासिल करने की उम्मीद करते हैं।
जॉन स्कीट

@JonSkeet: मैं ऑब्जेक्ट से फ़ंक्शन को कॉल करने में सक्षम होना चाहता हूं। वर्तमान में obj.MyFunction();संकलन नहीं है, भले ही मुझे पता है कि वास्तविक वस्तु में वह कार्य है।
पॉल लैस्सर

@ psubsee2003: नहीं, यह नहीं है, क्योंकि यह एक वस्तु संदर्भ है जिसे इंटरोप द्वारा पारित किया जा रहा है।
पॉल लैसिटर

3
@PaLLassiter: यदि आप प्रकार नहीं जानते हैं, तो MyFunctionविधि क्या घोषित करती है?
जॉन स्कीट

जवाबों:


194

यदि आप वास्तविक प्रकार जानते हैं, तो बस:

SomeType typed = (SomeType)obj;
typed.MyFunction();

यदि आप वास्तविक प्रकार नहीं जानते हैं, तो: वास्तव में नहीं, नहीं। आपको इसके बजाय एक का उपयोग करना होगा:

  • प्रतिबिंब
  • एक प्रसिद्ध इंटरफ़ेस लागू करना
  • गतिशील

उदाहरण के लिए:

// reflection
obj.GetType().GetMethod("MyFunction").Invoke(obj, null);

// interface
IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction
foo.MyFunction();

// dynamic
dynamic d = obj;
d.MyFunction();

1
स्विफ्ट में बराबर सिंटैक्स क्या है?
नागेंद्र राव

1
कोई बात नहीं, asटाइपकास्ट करने के लिए पाया गया और type(of: ClassName)उदाहरण के प्रकार की जाँच करने के लिए कार्य किया।
नागेंद्र राव

43

मुझे नहीं लगता कि आप कर सकते हैं (प्रतिबिंब के बिना नहीं), आपको अपने कार्य को एक प्रकार प्रदान करना चाहिए:

void MyMethod(Object obj, Type t)
{
    var convertedObject = Convert.ChangeType(obj, t);
    ...
}

UPD :

यह आपके लिए काम कर सकता है:

void MyMethod(Object obj)
{
    if (obj is A)
    {
        A a = obj as A;
        ...
    } 
    else if (obj is B)
    {
        B b = obj as B;
        ...
    }
}

4
यह वास्तव में एक बेकार जवाब है, अप-वोटों का अवांछनीय। ओपी द्वारा पूछे गए प्रकार के ऑब्जेक्ट के प्रतिबिंब को ऑब्जेक्ट के "वास्तविक प्रकार" का उत्पादन नहीं होगा। इसके अलावा, आपका MyMethod तर्क त्रुटिपूर्ण है क्योंकि obj प्रकार A का हो सकता है और यह भी प्रकार बी का हो सकता है। आपका तर्क "वास्तविक प्रकार" (जैसा कि ओपी ने अनुरोध किया है) प्रदान नहीं करता है - यह एक संगत प्रकार प्रदान करता है, और आवश्यक नहीं है उस पर वांछित प्रकार।
जजीमोव

obj.GetType () का उपयोग करें। यह निश्चित रूप से वापस आ जाएगा यह वास्तविक प्रकार है।
जोंस

3

कैसे के बारे में JsonConvert.DeserializeObject (object.ToString ());


यह संतोषजनक जवाब नहीं है। ओपी के सवाल का जसन या धारावाहिकीकरण से कोई लेना-देना नहीं है।

@ user12637955 यह वास्तव में एक कार्यशील उत्तर है, लेकिन इसमें बड़ी जटिलता है, बॉक्सिंग और अनबॉक्सिंग के कारण, अर्थात ऑब्जेक्ट -> ToString () -> से ठोस प्रकार। अधिक सटीक होने के लिए इसे इस तरह दिखना चाहिए:var myType = JsonConvert.DeserializeObject<MyType>(object.ToString());
कोक

1

मेरे मामले में AutoMapper अच्छा काम करता है।

AutoMapper गतिशील वस्तुओं से / बिना किसी स्पष्ट विन्यास के मैप कर सकता है:

public class Foo {
    public int Bar { get; set; }
    public int Baz { get; set; }
}
dynamic foo = new MyDynamicObject();
foo.Bar = 5;
foo.Baz = 6;

Mapper.Initialize(cfg => {});

var result = Mapper.Map<Foo>(foo);
result.Bar.ShouldEqual(5);
result.Baz.ShouldEqual(6);

dynamic foo2 = Mapper.Map<MyDynamicObject>(result);
foo2.Bar.ShouldEqual(5);
foo2.Baz.ShouldEqual(6);

इसी तरह आप शब्दकोशों से वस्तुओं तक सीधे मैप कर सकते हैं, AutoMapper संपत्ति नामों के साथ कुंजियों को पंक्तिबद्ध करेगा।

अधिक जानकारी https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping


1

यह विधि सबसे कुशल नहीं हो सकती है, लेकिन सरल है और काम करती है।

यह दो ऑपरेशन करता है: सबसे पहले यह कॉल करता है। TStString () जो कि मूल रूप से क्रमबद्धता है, और फिर न्यूटनसॉफ्ट नगेट (जिसे आपको इंस्टॉल करना होगा ) का उपयोग करके डीरिएशन किया जाता है ।

public T Format<T>(Object obj) =>
    JsonConvert.DeserializeObject<T>(obj.ToString());

आपको भविष्य के पाठकों के लिए अपने उत्तर का संक्षेप में वर्णन करना चाहिए।
सूरज कुमार

0

यदि आपकी MyFunction()विधि केवल एक वर्ग (और उसके वंशज) में परिभाषित है, तो प्रयास करें

void MyMethod(Object obj) 
{
    var o = obj as MyClass;
    if (o != null)
        o.MyFunction();
}

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

interface IMyInterface
{
    void MyFunction();
}

void MyMethod(Object obj) 
{
    var o = obj as IMyInterface;
    if (o != null)
        o.MyFunction();
}

0

यदि आप अब इसे उदाहरण के लिए टाइप करते हैं, तो इसे अपने वास्तविक प्रकार में डालें, यह एबीसी नाम की कक्षा से उन्मुख है। आप अपने फ़ंक्शन को इस तरह से कॉल कर सकते हैं:

(abc)(obj)).MyFunction();

यदि आप फ़ंक्शन को नहीं जानते हैं तो इसे एक अलग तरीके से किया जा सकता है। हमेशा आसान नहीं होता। लेकिन आप इसे हस्ताक्षर द्वारा किसी तरह से पा सकते हैं। यदि यह आपका मामला है, तो आपको हमें बताना चाहिए।


-1

वास्तविक प्रकार की कास्टिंग आसान है:

void MyMethod(Object obj) {
    ActualType actualyType = (ActualType)obj;
}

8
यह अतार्किक है। आप वास्तव में वास्तविक प्रकार नहीं जानते हैं। आप ऐसा कैसे करने वाले हैं?
एलन लिनाटॉक

-2
Implement an interface to call your function in your method
interface IMyInterface
{
 void MyinterfaceMethod();
}

IMyInterface MyObj = obj as IMyInterface;
if ( MyObj != null)
{
MyMethod(IMyInterface MyObj );
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.