शब्दकोश परिवर्तित करें <स्ट्रिंग, ऑब्जेक्ट> अनाम वस्तु के लिए?


81

सबसे पहले, और चीजों को स्पष्ट करने के लिए मैं अपने परिदृश्य को ऊपर से समझाऊंगा:

मेरे पास एक विधि है जिसमें निम्नलिखित हस्ताक्षर हैं:

public virtual void SendEmail(String from, List<String> recepients, Object model)

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

क्या यह संभव है? कोई अन्य सुझाव?


क्या आप ऐसा करना चाहते हैं?
मटियास जैकबसन

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

@ रूप: वास्तव में, यह एक उचित विकल्प भी है। मुझे पहले से ही एक शॉर्टकट मिल गया है जो मेरी आवश्यकताओं के लिए अच्छा काम करता है, लेकिन मैं अभी भी अपने प्रश्न का उत्तर जानना चाहूंगा ... बस जिज्ञासा से बाहर :)
Kassem

निम्नलिखित लिंक की जाँच करें, गुमनाम प्रकार के रूपांतरण के लिए शब्दकोश का बहुत अच्छा समाधान: jacobcarpenter.wordpress.com/2008/03/13/… tomsundev.wordpress.com/2011/07/20/…
मृणाल कांबोज

जवाबों:


116

यदि आप वास्तव में शब्दकोश को किसी ऐसी वस्तु में बदलना चाहते हैं, जिसमें शब्दकोष के गुण हैं, तो आप इसका उपयोग कर सकते हैं ExpandoObject:

var dict = new Dictionary<string, object> { { "Property", "foo" } };
var eo = new ExpandoObject();
var eoColl = (ICollection<KeyValuePair<string, object>>)eo;

foreach (var kvp in dict)
{
    eoColl.Add(kvp);
}

dynamic eoDynamic = eo;

string value = eoDynamic.Property;

लेकिन मुझे यकीन नहीं है कि वह कैसे आपकी मदद करने जा रहा है।


1
+1 लेकिन मुझे यकीन नहीं है कि वह कैसे आपकी मदद करने जा रहा है।
रेयानमाड

Vb.net में एक ही काम कैसे करें?
Mojtaba Rezaeian

3
इस मामले पर कि आप कभी ऐसा क्यों करेंगे। जब आप किसी मॉडल को रेजर टेम्पलेट में पास करते हैं, तो शब्दकोश की तुलना में गतिशील वस्तु के साथ काम करना आसान होता है। इसलिए, यदि आपके पास एक शब्दकोश है तो आप उसे एक गतिशील वस्तु में बदलना चाहेंगे। फिर, अपने *। Cshtml टेम्पलेट में, स्थान-धारक इस तरह दिखते हैं: @ Model.Name, इसके बजाय: @Model ["Name"]।
dalenewman

साइड नोट: ExpandoObjectप्रतिबिंब के साथ काम नहीं करता है क्योंकि यह एक वास्तविक वस्तु नहीं है, इसलिए यदि आप किसी ऐसी चीज के लिए परिणाम दे रहे हैं जिसके लिए उस वस्तु की आवश्यकता होती है जो उस पर प्रतिबिंबित होगी जो समस्या को हल नहीं करती है। आपके विकल्प फैंसी डायनामिक प्रकार के निर्माण (शायद benohead.com/blog/2013/12/26/… ) के रूप में दिखाई देते हैं या ... एक नया API ढूंढते / विकसित करते हैं जिसके लिए किसी ऑब्जेक्ट की आवश्यकता नहीं होती है जिसे परिलक्षित किया जा सके।
बंबाम्स

24

मैंने एक बयान में इसे कम करने के कार्य (एग्रीगेट इन लिनक) के साथ करने की कोशिश की। नीचे दिया गया कोड स्वीकृत उत्तर के समान है:

var dict = new Dictionary<string, object> { { "Property", "foo" } };
dynamic eo = dict.Aggregate(new ExpandoObject() as IDictionary<string, Object>,
                            (a, p) => { a.Add(p.Key, p.Value); return a; });
string value = eo.Property;

11

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

उदाहरण वर्ग:

public class Properties1
{
    public string Property { get; set; }
}

समाधान:

JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dict = new Dictionary<string, object> { { "Property", "foo" } };
Properties1 properties = serializer.ConvertToType<Properties1>(dict);
string value = properties.Property;

आप डिक्शनरी से ऑब्जेक्ट बनाने के लिए इस तरह की विधि का उपयोग कर सकते हैं, जाहिर है इसके लिए भी आपको एक क्लास की आवश्यकता होती है।

private static T DictionaryToObject<T>(IDictionary<string, object> dict) where T : new()
{
    T t = new T();
    PropertyInfo[] properties = t.GetType().GetProperties();

    foreach (PropertyInfo property in properties)
    {
        if (!dict.Any(x => x.Key.Equals(property.Name, 
            StringComparison.InvariantCultureIgnoreCase)))
            continue;
        KeyValuePair<string, object> item = dict.First(x => x.Key.Equals(property.Name,
            StringComparison.InvariantCultureIgnoreCase));
        Type tPropertyType = t.GetType().GetProperty(property.Name).PropertyType;
        Type newT = Nullable.GetUnderlyingType(tPropertyType) ?? tPropertyType;
        object newA = Convert.ChangeType(item.Value, newT);
        t.GetType().GetProperty(property.Name).SetValue(t, newA, null);
    }
    return t;
}

हालाँकि यदि आपके पास कक्षा नहीं है तो आप इस तरह से एक शब्दकोश से एक गतिशील वस्तु बना सकते हैं:

private static dynamic DictionaryToObject(Dictionary<string, object> dict)
{
    IDictionary<string, object> eo = (IDictionary<string, object>)new ExpandoObject();
    foreach (KeyValuePair<string, object> kvp in dict)
    {
        eo.Add(kvp);
    }
    return eo;
}

आप इसे इस तरह से उपयोग कर सकते हैं:

Dictionary<string, object> dict = new Dictionary<string, object> {{ "Property", "foo" }};
dynamic properties = DictionaryToObject(dict);
string value = properties.Property;

6

अगर आप Dictionary<string, object>To Anonymous कन्वर्ट करना चाहते हैं System.Object। आप इस विधि का उपयोग कर सकते हैं:

public static object FromDictToAnonymousObj<TValue>(IDictionary<string, TValue> dict)
{
    var types = new Type[dict.Count];

    for (int i = 0; i < types.Length; i++)
    {
        types[i] = typeof(TValue);
    }

    // dictionaries don't have an order, so we force an order based
    // on the Key
    var ordered = dict.OrderBy(x => x.Key).ToArray();

    string[] names = Array.ConvertAll(ordered, x => x.Key);

    Type type = AnonymousType.CreateType(types, names);

    object[] values = Array.ConvertAll(ordered, x => (object)x.Value);

    object obj = type.GetConstructor(types).Invoke(values);

    return obj;
}

इस तरह:

var dict = new Dictionary<string, string>
{
    {"Id", "1"},
    {"Title", "My title"},
    {"Description", "Blah blah blah"},
};

object obj1 = FromDictToAnonymousObj(dict);

अपनी वस्तु प्राप्त करने के लिए। AnonymousTypeकक्षा कोड कहां है:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;

/// <summary>
/// The code generated should be nearly equal to the one generated by
/// csc 12.0.31101.0 when compiling with /optimize+ /debug-. The main
/// difference is in the GetHashCode() (the base init_hash used is 
/// compiler-dependant) and in the maxstack of the generated methods.
/// Note that Roslyn (at least the one present at 
/// tryroslyn.azurewebsites.net) generates different code for anonymous
/// types.
/// </summary>
public static class AnonymousType
{
    private static readonly ConcurrentDictionary<string, Type> GeneratedTypes = new ConcurrentDictionary<string, Type>();

    private static readonly AssemblyBuilder AssemblyBuilder;
    private static readonly ModuleBuilder ModuleBuilder;
    private static readonly string FileName;

    // Some objects we cache
    private static readonly CustomAttributeBuilder CompilerGeneratedAttributeBuilder = new CustomAttributeBuilder(typeof(CompilerGeneratedAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
    private static readonly CustomAttributeBuilder DebuggerBrowsableAttributeBuilder = new CustomAttributeBuilder(typeof(DebuggerBrowsableAttribute).GetConstructor(new[] { typeof(DebuggerBrowsableState) }), new object[] { DebuggerBrowsableState.Never });
    private static readonly CustomAttributeBuilder DebuggerHiddenAttributeBuilder = new CustomAttributeBuilder(typeof(DebuggerHiddenAttribute).GetConstructor(Type.EmptyTypes), new object[0]);

    private static readonly ConstructorInfo ObjectCtor = typeof(object).GetConstructor(Type.EmptyTypes);
    private static readonly MethodInfo ObjectToString = typeof(object).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);

    private static readonly ConstructorInfo StringBuilderCtor = typeof(StringBuilder).GetConstructor(Type.EmptyTypes);
    private static readonly MethodInfo StringBuilderAppendString = typeof(StringBuilder).GetMethod("Append", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(string) }, null);
    private static readonly MethodInfo StringBuilderAppendObject = typeof(StringBuilder).GetMethod("Append", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(object) }, null);

    private static readonly Type EqualityComparer = typeof(EqualityComparer<>);
    private static readonly Type EqualityComparerGenericArgument = EqualityComparer.GetGenericArguments()[0];
    private static readonly MethodInfo EqualityComparerDefault = EqualityComparer.GetMethod("get_Default", BindingFlags.Static | BindingFlags.Public, null, Type.EmptyTypes, null);
    private static readonly MethodInfo EqualityComparerEquals = EqualityComparer.GetMethod("Equals", BindingFlags.Instance | BindingFlags.Public, null, new[] { EqualityComparerGenericArgument, EqualityComparerGenericArgument }, null);
    private static readonly MethodInfo EqualityComparerGetHashCode = EqualityComparer.GetMethod("GetHashCode", BindingFlags.Instance | BindingFlags.Public, null, new[] { EqualityComparerGenericArgument }, null);

    private static int Index = -1;

    static AnonymousType()
    {
        var assemblyName = new AssemblyName("AnonymousTypes");

        FileName = assemblyName.Name + ".dll";

        AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder = AssemblyBuilder.DefineDynamicModule("AnonymousTypes", FileName);
    }

    public static void Dump()
    {
        AssemblyBuilder.Save(FileName);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="types"></param>
    /// <param name="names"></param>
    /// <returns></returns>
    public static Type CreateType(Type[] types, string[] names)
    {
        if (types == null)
        {
            throw new ArgumentNullException("types");
        }

        if (names == null)
        {
            throw new ArgumentNullException("names");
        }

        if (types.Length != names.Length)
        {
            throw new ArgumentException("names");
        }

        // Anonymous classes are generics based. The generic classes
        // are distinguished by number of parameters and name of 
        // parameters. The specific types of the parameters are the 
        // generic arguments. We recreate this by creating a fullName
        // composed of all the property names, separated by a "|"
        string fullName = string.Join("|", names.Select(x => Escape(x)));

        Type type;

        if (!GeneratedTypes.TryGetValue(fullName, out type))
        {
            // We create only a single class at a time, through this lock
            // Note that this is a variant of the double-checked locking.
            // It is safe because we are using a thread safe class.
            lock (GeneratedTypes)
            {
                if (!GeneratedTypes.TryGetValue(fullName, out type))
                {
                    int index = Interlocked.Increment(ref Index);

                    string name = names.Length != 0 ? string.Format("<>f__AnonymousType{0}`{1}", index, names.Length) : string.Format("<>f__AnonymousType{0}", index);
                    TypeBuilder tb = ModuleBuilder.DefineType(name, TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.AutoLayout | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit);
                    tb.SetCustomAttribute(CompilerGeneratedAttributeBuilder);

                    GenericTypeParameterBuilder[] generics = null;

                    if (names.Length != 0)
                    {
                        string[] genericNames = Array.ConvertAll(names, x => string.Format("<{0}>j__TPar", x));
                        generics = tb.DefineGenericParameters(genericNames);
                    }
                    else
                    {
                        generics = new GenericTypeParameterBuilder[0];
                    }

                    // .ctor
                    ConstructorBuilder constructor = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, generics);
                    constructor.SetCustomAttribute(DebuggerHiddenAttributeBuilder);
                    ILGenerator ilgeneratorConstructor = constructor.GetILGenerator();
                    ilgeneratorConstructor.Emit(OpCodes.Ldarg_0);
                    ilgeneratorConstructor.Emit(OpCodes.Call, ObjectCtor);

                    var fields = new FieldBuilder[names.Length];

                    // There are two for cycles because we want to have
                    // all the getter methods before all the other 
                    // methods
                    for (int i = 0; i < names.Length; i++)
                    {
                        // field
                        fields[i] = tb.DefineField(string.Format("<{0}>i__Field", names[i]), generics[i], FieldAttributes.Private | FieldAttributes.InitOnly);
                        fields[i].SetCustomAttribute(DebuggerBrowsableAttributeBuilder);

                        // .ctor
                        constructor.DefineParameter(i + 1, ParameterAttributes.None, names[i]);
                        ilgeneratorConstructor.Emit(OpCodes.Ldarg_0);

                        if (i == 0)
                        {
                            ilgeneratorConstructor.Emit(OpCodes.Ldarg_1);
                        }
                        else if (i == 1)
                        {
                            ilgeneratorConstructor.Emit(OpCodes.Ldarg_2);
                        }
                        else if (i == 2)
                        {
                            ilgeneratorConstructor.Emit(OpCodes.Ldarg_3);
                        }
                        else if (i < 255)
                        {
                            ilgeneratorConstructor.Emit(OpCodes.Ldarg_S, (byte)(i + 1));
                        }
                        else
                        {
                            // Ldarg uses a ushort, but the Emit only
                            // accepts short, so we use a unchecked(...),
                            // cast to short and let the CLR interpret it
                            // as ushort
                            ilgeneratorConstructor.Emit(OpCodes.Ldarg, unchecked((short)(i + 1)));
                        }

                        ilgeneratorConstructor.Emit(OpCodes.Stfld, fields[i]);

                        // getter
                        MethodBuilder getter = tb.DefineMethod(string.Format("get_{0}", names[i]), MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, generics[i], Type.EmptyTypes);
                        ILGenerator ilgeneratorGetter = getter.GetILGenerator();
                        ilgeneratorGetter.Emit(OpCodes.Ldarg_0);
                        ilgeneratorGetter.Emit(OpCodes.Ldfld, fields[i]);
                        ilgeneratorGetter.Emit(OpCodes.Ret);

                        PropertyBuilder property = tb.DefineProperty(names[i], PropertyAttributes.None, CallingConventions.HasThis, generics[i], Type.EmptyTypes);
                        property.SetGetMethod(getter);
                    }

                    // ToString()
                    MethodBuilder toString = tb.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(string), Type.EmptyTypes);
                    toString.SetCustomAttribute(DebuggerHiddenAttributeBuilder);
                    ILGenerator ilgeneratorToString = toString.GetILGenerator();

                    ilgeneratorToString.DeclareLocal(typeof(StringBuilder));

                    ilgeneratorToString.Emit(OpCodes.Newobj, StringBuilderCtor);
                    ilgeneratorToString.Emit(OpCodes.Stloc_0);

                    // Equals
                    MethodBuilder equals = tb.DefineMethod("Equals", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(bool), new[] { typeof(object) });
                    equals.SetCustomAttribute(DebuggerHiddenAttributeBuilder);
                    equals.DefineParameter(1, ParameterAttributes.None, "value");
                    ILGenerator ilgeneratorEquals = equals.GetILGenerator();
                    ilgeneratorEquals.DeclareLocal(tb);

                    ilgeneratorEquals.Emit(OpCodes.Ldarg_1);
                    ilgeneratorEquals.Emit(OpCodes.Isinst, tb);
                    ilgeneratorEquals.Emit(OpCodes.Stloc_0);
                    ilgeneratorEquals.Emit(OpCodes.Ldloc_0);

                    Label equalsLabel = ilgeneratorEquals.DefineLabel();

                    // GetHashCode()
                    MethodBuilder getHashCode = tb.DefineMethod("GetHashCode", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(int), Type.EmptyTypes);
                    getHashCode.SetCustomAttribute(DebuggerHiddenAttributeBuilder);
                    ILGenerator ilgeneratorGetHashCode = getHashCode.GetILGenerator();
                    ilgeneratorGetHashCode.DeclareLocal(typeof(int));

                    if (names.Length == 0)
                    {
                        ilgeneratorGetHashCode.Emit(OpCodes.Ldc_I4_0);
                    }
                    else
                    {
                        // As done by Roslyn
                        // Note that initHash can vary, because
                        // string.GetHashCode() isn't "stable" for 
                        // different compilation of the code
                        int initHash = 0;

                        for (int i = 0; i < names.Length; i++)
                        {
                            initHash = unchecked(initHash * (-1521134295) + fields[i].Name.GetHashCode());
                        }

                        // Note that the CSC seems to generate a 
                        // different seed for every anonymous class
                        ilgeneratorGetHashCode.Emit(OpCodes.Ldc_I4, initHash);
                    }

                    for (int i = 0; i < names.Length; i++)
                    {
                        // Equals()
                        Type equalityComparerT = EqualityComparer.MakeGenericType(generics[i]);
                        MethodInfo equalityComparerTDefault = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerDefault);
                        MethodInfo equalityComparerTEquals = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerEquals);

                        ilgeneratorEquals.Emit(OpCodes.Brfalse_S, equalsLabel);
                        ilgeneratorEquals.Emit(OpCodes.Call, equalityComparerTDefault);
                        ilgeneratorEquals.Emit(OpCodes.Ldarg_0);
                        ilgeneratorEquals.Emit(OpCodes.Ldfld, fields[i]);
                        ilgeneratorEquals.Emit(OpCodes.Ldloc_0);
                        ilgeneratorEquals.Emit(OpCodes.Ldfld, fields[i]);
                        ilgeneratorEquals.Emit(OpCodes.Callvirt, equalityComparerTEquals);

                        // GetHashCode();
                        MethodInfo EqualityComparerTGetHashCode = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerGetHashCode);

                        ilgeneratorGetHashCode.Emit(OpCodes.Stloc_0);
                        ilgeneratorGetHashCode.Emit(OpCodes.Ldc_I4, -1521134295);
                        ilgeneratorGetHashCode.Emit(OpCodes.Ldloc_0);
                        ilgeneratorGetHashCode.Emit(OpCodes.Mul);
                        ilgeneratorGetHashCode.Emit(OpCodes.Call, EqualityComparerDefault);
                        ilgeneratorGetHashCode.Emit(OpCodes.Ldarg_0);
                        ilgeneratorGetHashCode.Emit(OpCodes.Ldfld, fields[i]);
                        ilgeneratorGetHashCode.Emit(OpCodes.Callvirt, EqualityComparerGetHashCode);
                        ilgeneratorGetHashCode.Emit(OpCodes.Add);

                        // ToString()
                        ilgeneratorToString.Emit(OpCodes.Ldloc_0);
                        ilgeneratorToString.Emit(OpCodes.Ldstr, i == 0 ? string.Format("{{ {0} = ", names[i]) : string.Format(", {0} = ", names[i]));
                        ilgeneratorToString.Emit(OpCodes.Callvirt, StringBuilderAppendString);
                        ilgeneratorToString.Emit(OpCodes.Pop);
                        ilgeneratorToString.Emit(OpCodes.Ldloc_0);
                        ilgeneratorToString.Emit(OpCodes.Ldarg_0);
                        ilgeneratorToString.Emit(OpCodes.Ldfld, fields[i]);
                        ilgeneratorToString.Emit(OpCodes.Box, generics[i]);
                        ilgeneratorToString.Emit(OpCodes.Callvirt, StringBuilderAppendObject);
                        ilgeneratorToString.Emit(OpCodes.Pop);
                    }

                    // .ctor
                    ilgeneratorConstructor.Emit(OpCodes.Ret);

                    // Equals()
                    if (names.Length == 0)
                    {
                        ilgeneratorEquals.Emit(OpCodes.Ldnull);
                        ilgeneratorEquals.Emit(OpCodes.Ceq);
                        ilgeneratorEquals.Emit(OpCodes.Ldc_I4_0);
                        ilgeneratorEquals.Emit(OpCodes.Ceq);
                    }
                    else
                    {
                        ilgeneratorEquals.Emit(OpCodes.Ret);
                        ilgeneratorEquals.MarkLabel(equalsLabel);
                        ilgeneratorEquals.Emit(OpCodes.Ldc_I4_0);
                    }

                    ilgeneratorEquals.Emit(OpCodes.Ret);

                    // GetHashCode()
                    ilgeneratorGetHashCode.Emit(OpCodes.Stloc_0);
                    ilgeneratorGetHashCode.Emit(OpCodes.Ldloc_0);
                    ilgeneratorGetHashCode.Emit(OpCodes.Ret);

                    // ToString()
                    ilgeneratorToString.Emit(OpCodes.Ldloc_0);
                    ilgeneratorToString.Emit(OpCodes.Ldstr, names.Length == 0 ? "{ }" : " }");
                    ilgeneratorToString.Emit(OpCodes.Callvirt, StringBuilderAppendString);
                    ilgeneratorToString.Emit(OpCodes.Pop);
                    ilgeneratorToString.Emit(OpCodes.Ldloc_0);
                    ilgeneratorToString.Emit(OpCodes.Callvirt, ObjectToString);
                    ilgeneratorToString.Emit(OpCodes.Ret);

                    type = tb.CreateType();

                    type = GeneratedTypes.GetOrAdd(fullName, type);
                }
            }
        }

        if (types.Length != 0)
        {
            type = type.MakeGenericType(types);
        }

        return type;
    }

    private static string Escape(string str)
    {
        // We escape the \ with \\, so that we can safely escape the
        // "|" (that we use as a separator) with "\|"
        str = str.Replace(@"\", @"\\");
        str = str.Replace(@"|", @"\|");
        return str;
    }
}

संदर्भ: https://stackoverflow.com/a/29428640/2073920


क्या डॉटनेट कोर में AnonymousType का कोई कार्यान्वयन है
क्रूजर KID

@CruiserKID मैं किसी भी समान कार्यान्वयन के बारे में नहीं जानता। यद्यपि आप .NET कोर में अनाम प्रकारों को बना और हेरफेर कर सकते हैं जैसे आप .NET में कर सकते हैं
अब्दुल रऊफ

6

कुछ विस्तार विधियों का उपयोग करते हुए, svick के उत्तर का थोड़ा अधिक मॉड्यूलर संस्करण:

public static class Extensions
{
    public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            collection.Add(item);
        }
    }

    public static dynamic ToDynamicObject(this IDictionary<string, object> source)
    {
        ICollection<KeyValuePair<string, object>> someObject = new ExpandoObject();
        someObject.AddRange(source);
        return someObject;
    }
}

1
मुझे यह विचार पसंद आया। हालांकि, वहाँ कोई नहीं है ICollection.AddRange। आपको या तो एक्सटेंशन के उपयोग से AddRange की आपूर्ति करनी होगी या उपयोग करने का प्रयास करना होगाsource.ToList().ForEach(someObject.Add)
Nils

वूप्स, अच्छा कैच! मैं अपने विस्तार के तरीकों के लिए अभ्यस्त हूं, मैं उन्हें प्रदान करता हूं। जवाब अपडेट करेंगे।
गीर सगरबर्ग

3

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

क्या आप गतिशील वस्तुओं की कोशिश कर सकते हैं? परिणाम आपके लिए आवश्यक सभी गुणों के साथ एक ऑब्जेक्ट होगा।


1
हाँ एक गतिशील वस्तु एकदम सही होगी। एक उदाहरण प्रदान करने के लिए देखभाल?
कासेम

1
मुझे नहीं लगता कि यह एक सटीक कथन है, आप रनटाइम के दौरान सही सीएलआर प्रकार भी बना सकते हैं। मैं सोच भी नहीं सकता कि आप रनटाइम के लिए एक गुमनाम प्रकार क्यों नहीं बना सकते।
क्रिस मैरिसिक

3
@ChrisMarisic उत्तर से "आप ऐसी वस्तु का उत्सर्जन कर सकते हैं"। सुनिश्चित करें कि आप कर सकते हैं।
माइक शाली

5
यह एक उत्तर नहीं है, बल्कि एक टिप्पणी है।
जोतबे

@ जेटा, यह वास्तव में एक उत्तर है, अप्रत्यक्ष रूप से कह रहा है: "आप ऐसा नहीं कर सकते।" मेरा मानना ​​है कि यह एक गलत जवाब है, लेकिन सभी का जवाब एक ही है।
थीटा-मछली

1

यहाँ इसका श्रेय स्वीकृत उत्तर को जाता है। इसे जोड़ना क्योंकि मैं एक सूची बनाना चाहता था <Dictionary <string, object >> a List <गतिशील>। उद्देश्य एक डेटाबेस तालिका से रिकॉर्ड खींचने के लिए है। मैंने जो किया था यह रहा।

    public static List<dynamic> ListDictionaryToListDynamic(List<Dictionary<string,object>> dbRecords)
    {
        var eRecords = new List<dynamic>();
        foreach (var record in dbRecords)
        {
            var eRecord = new ExpandoObject() as IDictionary<string, object>;
            foreach (var kvp in record)
            {
                eRecord.Add(kvp);
            }
            eRecords.Add(eRecord);
        }
        return eRecords;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.