গৃহীত উত্তর সঠিকভাবে বর্ণনা করে যে তালিকাটি কীভাবে ঘোষণা করা উচিত এবং বেশিরভাগ পরিস্থিতিতে তার জন্য অত্যন্ত প্রস্তাবিত।
তবে আমি একটি ভিন্ন দৃশ্য জুড়ে এসেছি, যা জিজ্ঞাসিত প্রশ্নকেও coversেকে দেয়। আপনি যদি একটি বিদ্যমান বস্তুর তালিকা ব্যবহার করতে চান কি আছে যদি ViewData["htmlAttributes"]
এ MVC ? আপনি কীভাবে এর বৈশিষ্ট্যগুলি অ্যাক্সেস করতে পারেন (সেগুলি সাধারণত মাধ্যমে তৈরি করা হয় new { @style="width: 100px", ... }
)?
এই সামান্য ভিন্ন দৃশ্যের জন্য আমি যা জানতে পেরেছিলাম তা আপনার সাথে ভাগ করে নিতে চাই। নীচের সমাধানগুলিতে, আমি নিম্নলিখিত ঘোষণাটি ধরে নিচ্ছি nodes
:
List<object> nodes = new List<object>();
nodes.Add(
new
{
Checked = false,
depth = 1,
id = "div_1"
});
1. গতিশীল সঙ্গে সমাধান
ইন সি # 4.0 এবং উচ্চতর সংস্করণ আপনি কেবল গতিশীল এবং লিখতে কাস্ট করতে পারেন:
if (nodes.Any(n => ((dynamic)n).Checked == false))
Console.WriteLine("found not checked element!");
নোট: এই ব্যবহার করছে প্রয়াত বাঁধাই, যার মানে হচ্ছে এটা শুধুমাত্র রানটাইম এ চিনতে পারবে যদি বস্তুর একটি নেই Checked
সম্পত্তি এবং ছোঁড়ার RuntimeBinderException
এই ক্ষেত্রে - তাই যদি আপনি একটি অ-বিদ্যমান ব্যবহারের চেষ্টা Checked2
সম্পত্তি আপনি নিম্নলিখিত বার্তা পেতে হবে এ রানটাইম: "'<>f__AnonymousType0<bool,int,string>' does not contain a definition for 'Checked2'"
।
2. প্রতিবিম্ব সঙ্গে সমাধান
প্রতিচ্ছবি সহ সমাধান পুরানো এবং নতুন সি # সংকলক সংস্করণ উভয়ই কাজ করে । পুরানো সি # সংস্করণের জন্য দয়া করে এই উত্তরটির শেষে ইঙ্গিতটি বিবেচনা করুন।
পটভূমি
একটি আদ্যস্থল হিসাবে, আমি একটি ভাল উত্তর পাওয়া এখানে । ভাবনাটি হ'ল প্রতিবিম্ব ব্যবহার করে বেনামে তথ্য প্রকারকে অভিধানে রূপান্তর করা। অভিধানগুলি বৈশিষ্ট্যগুলি অ্যাক্সেস করা সহজ করে তোলে, যেহেতু তাদের নামগুলি কী হিসাবে সংরক্ষণ করা হয় (আপনি তাদের মতো অ্যাক্সেস করতে পারেন myDict["myProperty"]
)।
উপরের লিঙ্কটি কোড দ্বারা অনুপ্রাণিত, আমি একটি এক্সটেনশন বর্গ প্রদানের নির্মিত GetProp
, UnanonymizeProperties
এবং UnanonymizeListItems
এক্সটেনশন পদ্ধতি, বেনামী বৈশিষ্ট্য যা প্রক্রিয়া সহজ অ্যাক্সেস করার অনুমতি। এই শ্রেণীর সাহায্যে আপনি নিম্নরূপে কোয়েরিটি সহজভাবে করতে পারেন:
if (nodes.UnanonymizeListItems().Any(n => (bool)n["Checked"] == false))
{
Console.WriteLine("found not checked element!");
}
অথবা আপনি শর্ত nodes.UnanonymizeListItems(x => (bool)x["Checked"] == false).Any()
হিসাবে অভিব্যক্তিটি ব্যবহার করতে পারেন if
, যা স্পষ্টভাবে ফিল্টার করে এবং তারপরে কোনও উপাদান ফিরে আসে কিনা তা পরীক্ষা করে।
"পরীক্ষিত" বৈশিষ্ট্যযুক্ত প্রথম বস্তুটি পেতে এবং এর সম্পত্তি "গভীরতা" ফিরিয়ে আনতে আপনি ব্যবহার করতে পারেন:
var depth = nodes.UnanonymizeListItems()
?.FirstOrDefault(n => n.Contains("Checked")).GetProp("depth");
বা সংক্ষিপ্ত: nodes.UnanonymizeListItems()?.FirstOrDefault(n => n.Contains("Checked"))?["depth"];
দ্রষ্টব্য: আপনার যদি অবজেক্টগুলির একটি তালিকা থাকে যা অগত্যা সমস্ত বৈশিষ্ট্য ধারণ করে না (উদাহরণস্বরূপ, কিছুতে "চেক করা" বৈশিষ্ট্য নেই) এবং আপনি এখনও "পরীক্ষিত" মানগুলির উপর ভিত্তি করে একটি ক্যোয়ারী তৈরি করতে চান, আপনি এটি করতে পারেন এটা কর:
if (nodes.UnanonymizeListItems(x => { var y = ((bool?)x.GetProp("Checked", true));
return y.HasValue && y.Value == false;}).Any())
{
Console.WriteLine("found not checked element!");
}
এটি প্রতিরোধ করে, KeyNotFoundException
"চেক করা" সম্পত্তিটি উপস্থিত না থাকলে এমন একটি ঘটে।
নীচের শ্রেণিতে নিম্নলিখিত এক্সটেনশন পদ্ধতি রয়েছে:
UnanonymizeProperties
: কোনও বস্তুর মধ্যে থাকা বৈশিষ্ট্যগুলি ডি-বেনামে ব্যবহার করা হয় । এই পদ্ধতিতে প্রতিবিম্ব ব্যবহার করা হয়। এটি বস্তুটিকে বৈশিষ্ট্য এবং এর মান সমেত একটি অভিধানে রূপান্তরিত করে।
UnanonymizeListItems
: বৈশিষ্ট্যযুক্ত অভিধানের তালিকায় কোনও সামগ্রীর তালিকা রূপান্তর করতে ব্যবহৃত হয়। এটিতে আগে ফিল্টার করার জন্য optionচ্ছিকভাবে ল্যাম্বডা এক্সপ্রেশন থাকতে পারে ।
GetProp
: প্রদত্ত সম্পত্তি নামের সাথে একক মান ফেরত দিতে ব্যবহৃত হয়। কী-নটফাউন্ডএক্সেপশন (ভুয়া) না হয়ে অস্তিত্বের বৈশিষ্ট্যগুলিকে নাল মান (সত্য) হিসাবে বিবেচনা করার অনুমতি দেয়
উপরের উদাহরণগুলির জন্য, যা প্রয়োজন তা হ'ল আপনি নীচে এক্সটেনশন ক্লাস যুক্ত করুন:
public static class AnonymousTypeExtensions
{
// makes properties of object accessible
public static IDictionary UnanonymizeProperties(this object obj)
{
Type type = obj?.GetType();
var properties = type?.GetProperties()
?.Select(n => n.Name)
?.ToDictionary(k => k, k => type.GetProperty(k).GetValue(obj, null));
return properties;
}
// converts object list into list of properties that meet the filterCriteria
public static List<IDictionary> UnanonymizeListItems(this List<object> objectList,
Func<IDictionary<string, object>, bool> filterCriteria=default)
{
var accessibleList = new List<IDictionary>();
foreach (object obj in objectList)
{
var props = obj.UnanonymizeProperties();
if (filterCriteria == default
|| filterCriteria((IDictionary<string, object>)props) == true)
{ accessibleList.Add(props); }
}
return accessibleList;
}
// returns specific property, i.e. obj.GetProp(propertyName)
// requires prior usage of AccessListItems and selection of one element, because
// object needs to be a IDictionary<string, object>
public static object GetProp(this object obj, string propertyName,
bool treatNotFoundAsNull = false)
{
try
{
return ((System.Collections.Generic.IDictionary<string, object>)obj)
?[propertyName];
}
catch (KeyNotFoundException)
{
if (treatNotFoundAsNull) return default(object); else throw;
}
}
}
ইঙ্গিত: উপরের কোড ব্যবহার করছে নাল-শর্তাধীন অপারেটর, যেহেতু C # এর সংস্করণ 6.0 প্রাপ্তিসাধ্য - আপনি সাথে এসেছেন পরিশ্রমী পুরোনো C # এর কম্পাইলার (যেমন C # এর 3.0), কেবল প্রতিস্থাপন ?.
দ্বারা .
এবং ?[
দ্বারা [
, সর্বত্র যেমন
var depth = nodes.UnanonymizeListItems()
.FirstOrDefault(n => n.Contains("Checked"))["depth"];
যদি আপনাকে কোনও পুরানো সি # সংকলক ব্যবহার করতে বাধ্য করা না হয়, তবে এটি ঠিক রাখুন, কারণ নাল-কন্ডিশনাল ব্যবহার নাল পরিচালনা সহজতর করে তোলে।
দ্রষ্টব্য: ডায়নামিক সহ অন্যান্য সমাধানের মতো, এই সমাধানটিও দেরী বাঁধাই ব্যবহার করছে, তবে এই ক্ষেত্রে আপনি কোনও ব্যতিক্রম পাচ্ছেন না - আপনি যদি অ-বিদ্যমান সম্পত্তি হিসাবে উল্লেখ করছেন তবে এটি উপাদানটি খুঁজে পাবে না long আপনি নাল-শর্তযুক্ত অপারেটরদের রাখা হিসাবে ।
কিছু অ্যাপ্লিকেশনগুলির জন্য দরকারী যেটি হ'ল সম্পত্তিটি সমাধান 2-এ স্ট্রিংয়ের মাধ্যমে উল্লেখ করা হয়, তাই এটি প্যারামিটারাইজ করা যেতে পারে।