স্ট্রিংয়ের মাধ্যমে গ # গতিশীল সম্পত্তির মান পান


180

আমি dynamicএকটি স্ট্রিং সহ একটি সি # সম্পত্তিটির মানটি অ্যাক্সেস করতে চাই :

dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };

আমার কাছে যদি কেবল স্ট্রিং হিসাবে "মান 2" থাকে তবে আমি কীভাবে d.value2 ("এলোমেলো") এর মান পেতে পারি? জাভাস্ক্রিপ্টে, আমি মানটি ("এলোমেলো") অ্যাক্সেস করার জন্য ডি ["মান 2"] করতে পারতাম, তবে আমি সি # এবং প্রতিবিম্ব দিয়ে কীভাবে এটি করব তা নিশ্চিত নই। সবচেয়ে কাছাকাছি এসেছি এটি:

d.GetType().GetProperty("value2") ... তবে আমি জানি না যে কীভাবে থেকে আসল মান পাওয়া যায়।

সর্বদা হিসাবে, আপনার সাহায্যের জন্য ধন্যবাদ!


26
দ্রষ্টব্য যে এটি "গতিশীল" এর উদ্দেশ্যযুক্ত উদ্দেশ্য নয় এবং এই দৃশ্যটি "অবজেক্ট" এর চেয়ে "গতিশীল" এর সাথে আরও ভাল কাজ করে না। "গতিশীল" বৈশিষ্ট্য অ্যাক্সেস করা সম্ভব করে যখন সংস্থার সময় সম্পত্তির নাম জানা যায় তবে প্রকারটি থাকে না। আপনি যেহেতু সংকলনের সময় নাম বা প্রকার উভয়ই জানেন না, তাই গতিশীল আপনাকে সাহায্য করবে না।
এরিক লিপার্ট


3
@ এরিকলিপার্ট আমি জানি এই প্রশ্নটি পুরানো তবে ভবিষ্যতে কেউ যদি এটি দেখে তবে একটি মন্তব্য করতে make কিছু ক্ষেত্রে আপনি গতিশীল বা অবজেক্ট (উদাহরণস্বরূপ JSON পার্সার ব্যবহার করার সময়) ব্যবহার করবেন কিনা তা চয়ন করতে পারবেন না এবং আপনি এখনও স্ট্রিং থেকে (উদাহরণস্বরূপ কোনও কনফিগারেশন ফাইল থেকে) সম্পত্তি পেতে চান তাই এই ব্যবহারটি এমন অস্বাভাবিক নয় যেহেতু কেউ প্রথমে ভাবতে পারে।
পেড্রাম

উত্তর:


216

একবার আপনার PropertyInfo(থেকে GetProperty) হয়ে গেলে , আপনাকে কল করতে হবে GetValueএবং যে পরিমাণটি থেকে মানটি পেতে চান সেই ক্ষেত্রে আপনাকে পাস করতে হবে। তোমার ক্ষেত্রে:

d.GetType().GetProperty("value2").GetValue(d, null);

4
আমি সাথে একটি 'd.GetType().GetProperty("value2").GetValue(d)' threw an exception of type 'System.Reflection.TargetInvocationException' dynamic {System.Reflection.TargetInvocationException}ওয়াচ উইন্ডোতে পেয়ে যাচ্ছি ..?
টিমডগ

6
মনে GetValue একটি অতিরিক্ত প্যারামিটার প্রয়োজন -। EgdGetType () GetProperty ( "VALUE2") GetValue (ঘ, নাল)।
dommer

3
এটি কি কোনও বেনামি প্রকারের পরিবর্তে সত্যিকারের গতিশীল ExpandoObject এ কাজ করবে? যেহেতু new {}সংজ্ঞায়িত বৈশিষ্ট্যগুলির সাথে একটি আসল বেনামে প্রকার তৈরি করে, গেটটাইপ / গেটপ্রপার্টি কল করা অর্থপূর্ণ হয় তবে এক্সপান্ডোঅবজেক্টের কী, আপনি যদি গেটটাইপ কল করেন তবে আপনি এমন একটি প্রকার পাবেন যা এক্সপ্যান্ডোঅবজেক্টের বৈশিষ্ট্যযুক্ত তবে প্রয়োজনীয় গতিশীল বৈশিষ্ট্য নয়।
ত্রিঞ্চো

16
-1। এটি কেবলমাত্র সহজ .NET অবজেক্টের সাথে কাজ করে যা গতিশীল হয়ে গেছে। এটি কোনও কাস্টম গতিশীল অবজেক্টের মতো কাজ করবে না যেমন এক্সপ্যান্ডো বা ভিউব্যাগ ব্যবহৃত এএসপি.নেট এমভিসি
ফিলিপ মুনিন

8
এটিই এক্সপ্যান্ডো অবজেক্টের সাথে কাজ করে: ((আইডিশিয়ুরি <স্ট্রিং, অবজেক্ট>) x)) ["মান 1"]
মাইকেল বাহিগ

39
public static object GetProperty(object target, string name)
{
    var site = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, name, target.GetType(), new[]{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0,null)}));
    return site.Target(site, target);
}

মাইক্রোসফ্ট.সিএসআরপ-এ রেফারেন্স যুক্ত করুন। গতিশীল ধরণের এবং ব্যক্তিগত সম্পত্তি এবং ক্ষেত্রগুলির জন্যও কাজ করে।

সম্পাদনা করুন : এই পদ্ধতির কাজ করার সময়, মাইক্রোসফ্ট থেকে প্রায় 20 × দ্রুত পদ্ধতি রয়েছে is ভিজুয়ালবাসিক.ডিল সমাবেশ:

public static object GetProperty(object target, string name)
{
    return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get);
}

2
কেবল উল্লেখ করতে চেয়েছিলেন যে ভিজ্যুয়াল বেসিক সংস্করণটি আপনার মূল 'গেটপোপার্টি' সংস্করণের সমতুল্য নয় (গেটপোপার্টি আসলে ডায়নামিক গেটমেম্বারকে আহ্বান করে যা আয়রন পাইথনের পাইথন অবজেক্টগুলিতেও কাজ করে)।
ট্রেভর সানডবার্গ

উদ্দেশ্য লক্ষ্য কি হবে?
ডিওমডেভ

@ ডেমোডাভ সেই বস্তুটি যার উপরে আপনি সম্পত্তিটি চাওয়াতে চান ( dপ্রশ্নে)।
ইলিডানএস 4 মনিকা

Fast1 এটি ব্যক্তিগত সম্পত্তিগুলির জন্য কাজ করেছিল যখন ফাস্টমেম্বার এবং হাইপারডেস্কিটার উভয়ই না
ক্রিস মেরিসিক

@ IllidanS4 আপনি CallSiteকোড বনাম CallByNameকোড তুলনা করার সময় CallSiteউদাহরণটি ক্যাশে করার সময় আপনি কি দুটিটির তুলনা করেছেন ? আমি সন্দেহ করব যে আপনার প্রথম পদ্ধতির ব্যয় প্রায় BinderCallSiteTarget()
নিখুঁতভাবে

24

ডায়নামাইটে একটি ওপেন সোর্স .net stdলাইব্রেরি, যা আপনি এটি dynamicকীওয়ার্ডের মতো বলুন , তবে সংখ্যক সংস্থার পরিবর্তে সম্পত্তি নামের জন্য একটি স্ট্রিং ব্যবহার করে এটি আপনার জন্য দ্রুতগতির প্রতিফলনের সমান হয়ে যায় (যা প্রায় তত দ্রুত নয়) ডায়নামিক কীওয়ার্ড ব্যবহার করার মতো, তবে এটি গতিশীলভাবে ক্যাশিংয়ের অতিরিক্ত ওভারহেডের কারণে, যেখানে সংকলক স্থিতিশীলভাবে ক্যাশে করে)।

Dynamic.InvokeGet(d,"value2");

11

সম্পত্তি সহ যে কোনও ধরণের জন্য কাজ করে এবং এটি ব্যবহারের জন্য একটি setterএবং একটি উভয় প্রাপ্তির সবচেয়ে সহজ পদ্ধতি যা প্রায় দ্রুততম পদ্ধতি হিসাবে ঘটে (এটি এমিট ব্যবহার করে)।getterdynamicExpandoObjectFastMember

আপনি হয় TypeAccessorপ্রদত্ত প্রকারের ObjectAccessorভিত্তিতে বা প্রদত্ত প্রকারের উদাহরণের ভিত্তিতে পেতে পারেন ।

উদাহরণ:

var staticData = new Test { Id = 1, Name = "France" };
var objAccessor = ObjectAccessor.Create(staticData);
objAccessor["Id"].Should().Be(1);
objAccessor["Name"].Should().Be("France");

var anonymous = new { Id = 2, Name = "Hilton" };
objAccessor = ObjectAccessor.Create(anonymous);
objAccessor["Id"].Should().Be(2);
objAccessor["Name"].Should().Be("Hilton");

dynamic expando = new ExpandoObject();
expando.Id = 3;
expando.Name = "Monica";
objAccessor = ObjectAccessor.Create(expando);
objAccessor["Id"].Should().Be(3);
objAccessor["Name"].Should().Be("Monica");

var typeAccessor = TypeAccessor.Create(staticData.GetType());
typeAccessor[staticData, "Id"].Should().Be(1);
typeAccessor[staticData, "Name"].Should().Be("France");

typeAccessor = TypeAccessor.Create(anonymous.GetType());
typeAccessor[anonymous, "Id"].Should().Be(2);
typeAccessor[anonymous, "Name"].Should().Be("Hilton");

typeAccessor = TypeAccessor.Create(expando.GetType());
((int)typeAccessor[expando, "Id"]).Should().Be(3);
((string)typeAccessor[expando, "Name"]).Should().Be("Monica");

8

যখন আপনি ডায়নামিক অবজেক্টের জন্য জিজ্ঞাসা করেন তখন বেশিরভাগ সময় আপনি একটি এক্সপেন্ডোঅবজেক্ট পান (উপরের প্রশ্নটির বেনামে-তবে-স্ট্যাটিকালি-টাইপ করা উদাহরণে নয়, তবে আপনি জাভাস্ক্রিপ্ট এবং আমার নির্বাচিত জেএসওন পার্সার জেসনএফএক্স উল্লেখ করেছেন, একটির জন্য ExpandoObjects উত্পন্ন করে)।

যদি আপনার গতিশীল প্রকৃতপক্ষে কোনও ExpandoObject হয় তবে আপনি এটি আইডি অভিধানে কাস্ট করে প্রতিচ্ছবি এড়াতে পারবেন, যেমনটি http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx এ বর্ণিত

আপনি একবার আইডি অভিধানে কাস্ট করে নিলে আপনার কাছে। আইটেম এবং। কনটেনসকি এর মতো দরকারী পদ্ধতিতে অ্যাক্সেস থাকতে হবে


দুর্ভাগ্যক্রমে, আইডিকোরিয়ায় কাস্ট করা এবং উদাহরণস্বরূপ ট্রাইগেটভ্যালু ব্যবহার করা ফলস্বরূপ একটি সাধারণ প্লেট পুরানো বস্তু ফিরে আসবে। আপনি এই মুহুর্তে অন্তর্ভুক্ত অপারেটরদের সুবিধা নিতে পারবেন না, যেহেতু সেগুলি কেবল সংকলনের সময় বিবেচনা করা হয়। উদাহরণস্বরূপ, যদি আমার অন্তর্নিহিত রূপান্তরটি ইন্টার 64 এর সাথে একটি ইন্টার64 প্রক্সি ক্লাস হয় ?, তাহলে Int64? i = data.value; //data is ExpandoObjectস্বয়ংক্রিয়ভাবে অনুসন্ধানী এবং অন্তর্ভুক্ত অপারেটরটিকে কল করবে। অন্যদিকে, "মান" ক্ষেত্রটি বিদ্যমান কিনা তা পরীক্ষা করতে যদি আমাকে আইডিকোরি ব্যবহার করতে হয় তবে আমি এমন একটি বস্তু পেয়ে যাব যা ইন্টার 6464 এ ত্রুটি ছাড়াই নিক্ষেপ করবে না ?.
ত্রিণকো

5

গেটপ্রপার্টি / গেটভ্যালু জেসন ডেটার জন্য কাজ করে না, এটি সর্বদা নাল ব্যতিক্রম জেনারেট করে, তবে আপনি এই পদ্ধতির চেষ্টা করতে পারেন:

জেসনকন্টার্ট ব্যবহার করে আপনার অবজেক্টটি সিরিয়াল করুন:

var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));

তারপরে এটি সরাসরি স্ট্রিংয়ে castালাই অ্যাক্সেস করুন:

var pn = (string)z["DynamicFieldName"];

এটি কনভার্ট.টোলস্ট্রিং (অনুরোধ) ["ডায়নামিকফিল্ডনেম"] প্রয়োগ করে সরাসরি কাজ করতে পারে, তবে আমি পরীক্ষা করি নি।


2
এই পদ্ধতিটি ত্রুটি উত্পন্ন করে: ত্রুটি CS0021: 'অবজেক্ট' টাইপের অভিব্যক্তিতে [] এর সাথে সূচীকরণ প্রয়োগ করতে পারে না। new JavaScriptSerializer().Deserialize<object>(json);আপনি যেভাবে পরামর্শ দিয়েছেন সেভাবে "বৈশিষ্ট্যগুলি" পেতে ব্যবহার করুন
ক্রিস কিলটন

4

d.GetType ()। GetProperty ( "VALUE2")

একটি সম্পত্তিInfo অবজেক্ট প্রদান করে।

সুতরাং তারপর না

propertyInfo.GetValue(d)

2
ধন্যবাদ, এটি সঠিক উত্তর ছিল, তবে উপরে উল্লিখিত হিসাবে, হওয়া GetValue(d)দরকারGetValue(d,null)
টিমডগ

4

এইভাবেই আমি ডায়নামিকের একটি সম্পত্তি মানের মূল্য পেয়েছি:

    public dynamic Post(dynamic value)
    {            
        try
        {
            if (value != null)
            {
                var valorCampos = "";

                foreach (Newtonsoft.Json.Linq.JProperty item in value)
                {
                    if (item.Name == "valorCampo")//property name
                        valorCampos = item.Value.ToString();
                }                                           

            }
        }
        catch (Exception ex)
        {

        }


    }

1

.GetType()ফিরে আসার সময় গতিশীল ডক থেকে সম্পত্তি পেতে null, এটি চেষ্টা করুন:

var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;

0

নেট কোর 3.1 এ আপনি এটির মতো চেষ্টা করতে পারেন

d?.value2 , d?.value3

0

গৃহীত উত্তরের মতো, আপনি এর GetFieldপরিবর্তেও চেষ্টা করতে পারেন GetProperty

d.GetType().GetField("value2").GetValue(d);

আসল কীভাবে Typeবাস্তবায়িত হয়েছিল তার উপর নির্ভর করে , যখন getProperty () দ্রুত নাও হতে পারে তখন এটি কাজ করতে পারে।


: অবগতির জন্য C # 3.0+ সম্পত্তি এবং ফিল্ড মধ্যে পার্থক্য stackoverflow.com/a/653799/2680660
Efreeto
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.