गतिशील रूप से रनटाइम पर C # गुण जोड़ें


89

मुझे पता है कि कुछ ऐसे प्रश्न हैं जो इसे संबोधित करते हैं, लेकिन उत्तर आमतौर पर एक डिक्शनरी या कलेक्शन ऑफ पैरामीटर्स की सिफारिश की तर्ज पर चलते हैं, जो मेरी स्थिति में काम नहीं करता है।

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

public static object GetDynamicObject(Dictionary<string,object> properties) {
    var myObject = new object();
    foreach (var property in properties) {
        //This next line obviously doesn't work... 
        myObject.AddProperty(property.Key,property.Value);
    }
    return myObject;
}

public void Main() {
    var properties = new Dictionary<string,object>();
    properties.Add("Property1",aCustomClassInstance);
    properties.Add("Property2","TestString2");

    var myObject = GetDynamicObject(properties);

    //Then use them like this (or rather the plug in uses them through reflection)
    var customClass = myObject.Property1;
    var myString = myObject.Property2;

}

लायब्रेरी एक गतिशील चर प्रकार के साथ ठीक काम करती है, गुणों के साथ मैन्युअल रूप से असाइन की गई है। हालाँकि मुझे नहीं पता कि पहले से कितने या कौन से गुण जोड़े जाएंगे।

जवाबों:


105

क्या आपने ExpandoObject पर एक नज़र डाली है?

देखें: http://blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx

MSDN से:

एक्सपेंडेओबजेक्ट क्लास आपको अपने इंस्टेंस के सदस्यों को रन टाइम पर जोड़ने और हटाने के लिए और इन सदस्यों के मूल्यों को सेट और प्राप्त करने में सक्षम बनाता है। यह वर्ग डायनामिक बाइंडिंग का समर्थन करता है, जो आपको नमूनाऑब्जेक्ट की तरह मानक सिंटैक्स का उपयोग करने में सक्षम बनाता है। नमूनाऑब्जेक्ट की तरह अधिक जटिल सिंटैक्स के बजाय नमूना।

आपको ठंडी चीजें करने की अनुमति देना:

dynamic dynObject = new ExpandoObject();
dynObject.SomeDynamicProperty = "Hello!";
dynObject.SomeDynamicAction = (msg) =>
    {
        Console.WriteLine(msg);
    };

dynObject.SomeDynamicAction(dynObject.SomeDynamicProperty);

आपके वास्तविक कोड के आधार पर आपको इसमें अधिक रुचि हो सकती है:

public static dynamic GetDynamicObject(Dictionary<string, object> properties)
{
    return new MyDynObject(properties);
}

public sealed class MyDynObject : DynamicObject
{
    private readonly Dictionary<string, object> _properties;

    public MyDynObject(Dictionary<string, object> properties)
    {
        _properties = properties;
    }

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return _properties.Keys;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (_properties.ContainsKey(binder.Name))
        {
            result = _properties[binder.Name];
            return true;
        }
        else
        {
            result = null;
            return false;
        }
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (_properties.ContainsKey(binder.Name))
        {
            _properties[binder.Name] = value;
            return true;
        }
        else
        {
            return false;
        }
    }
}

इस तरह से आपको बस जरूरत है:

var dyn = GetDynamicObject(new Dictionary<string, object>()
    {
        {"prop1", 12},
    });

Console.WriteLine(dyn.prop1);
dyn.prop1 = 150;

डायनामिकऑब्जेक्ट से व्युत्पन्न आपको इन गतिशील सदस्य अनुरोधों को संभालने के लिए अपनी खुद की रणनीति के साथ आने की अनुमति देता है, यहां राक्षसों से सावधान रहें: कंपाइलर आपके बहुत सारे डायनामिक कॉल्स को सत्यापित नहीं कर पाएगा और आपको इंटेलीजेंस नहीं मिलेगा, इसलिए बस बने रहें मन में है कि।


39

धन्यवाद @ महान जवाब के लिए क्लिंट:

एक्सपेंडेओ ऑब्जेक्ट का उपयोग करके इसे हल करना कितना आसान था, इसे उजागर करना चाहता था:

    var dynamicObject = new ExpandoObject() as IDictionary<string, Object>;
    foreach (var property in properties) {
        dynamicObject.Add(property.Key,property.Value);
    }

3

आप एक शब्दकोश में अपने json स्ट्रिंग deserialize कर सकते हैं और फिर नए गुणों को जोड़ सकते हैं फिर इसे क्रमबद्ध करें।

 var jsonString = @"{}";

        var jsonDoc = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonString);

        jsonDoc.Add("Name", "Khurshid Ali");

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