c # foreach (বস্তুতে সম্পত্তি)… এটি করার কোন সহজ উপায় আছে?


92

আমার বেশ কয়েকটি বৈশিষ্ট্যযুক্ত একটি শ্রেণি রয়েছে (এটি যদি কোনও পার্থক্য করে তবে সমস্ত স্ট্রিং হয়)।
আমার কাছে একটি তালিকাও রয়েছে, যা ক্লাসের বিভিন্ন উদাহরণ রয়েছে।

আমার ক্লাসগুলির জন্য কিছু ইউনিট পরীক্ষা তৈরি করার সময় আমি সিদ্ধান্ত নিয়েছি যে আমি তালিকার প্রতিটি বস্তুর মধ্য দিয়ে লুপ করতে চাই এবং তারপরে সেই বস্তুর প্রতিটি সম্পত্তি দিয়ে লুপ করতে চাই ...

আমি ভেবেছিলাম এটি করা এতটা সহজ হবে ...

foreach (Object obj in theList)
{
     foreach (Property theProperties in obj)
     {
         do some stufff!!;
     }
}

কিন্তু এই কাজ না! :( আমি এই ত্রুটি পেয়েছি ...

"ফোরচ স্টেটমেন্ট 'অ্যাপ্লিকেশন.অবজেক্ট' টাইপের ভেরিয়েবলগুলিতে পরিচালনা করতে পারে না কারণ 'অ্যাপ্লিকেশন.অবজেক্ট' 'গেটইমুনিটার' এর জন্য সর্বজনীন সংজ্ঞা ধারণ করে না"

টন ইফ এবং লুপ ছাড়া বা খুব জটিল কিছু না পেয়েই কেউ এই কাজ করার কোনও উপায় জানেন?


4
ভবিষ্যতে, দয়া করে একটি প্রশ্নে "এটি কাজ করে না" বলবেন না। পরিবর্তে, আপনার যে সমস্যা হচ্ছে তা নির্দিষ্ট করুন (সংকলক ত্রুটি ইত্যাদি)। ধন্যবাদ!
রবার্ট হার্ভে

4
আপডেট হয়েছে! রবার্টের
শীর্ষস্থানীয়দের

উত্তর:


143

একবার চেষ্টা করে দেখুন:

foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties())
{
   // do stuff here
}

এছাড়াও দয়া করে নোট করুন যে Type.GetProperties()একটি ওভারলোড রয়েছে যা বাঁধাই পতাকাগুলির একটি সেট গ্রহণ করে যাতে আপনি অ্যাক্সেসিবিলিটি স্তরের মতো বিভিন্ন মানদণ্ডে বৈশিষ্ট্যগুলি ফিল্টার করতে পারেন, আরও তথ্যের জন্য এমএসডিএন দেখুন: টাইপ করুন। গেটপ্রপার্টি পদ্ধতি (বাইন্ডিংফ্লাগস) শেষ তবে ভুলে যাবেন না "সিস্টেম.প্রকাশন" সমাবেশ উল্লেখ করুন।

উদাহরণস্বরূপ সমস্ত জনসাধারণের সম্পত্তি সমাধান করার জন্য:

foreach (var propertyInfo in obj.GetType()
                                .GetProperties(
                                        BindingFlags.Public 
                                        | BindingFlags.Instance))
{
   // do stuff here
}

এটি প্রত্যাশার মতো কাজ করে কিনা তা আমাকে জানান।


4
একবার আপনার বস্তুর বৈশিষ্ট্যগুলির উপর একটি হ্যান্ডেল হয়ে গেলে, প্রতিটি সম্পত্তির মূল্য দখল করার কোনও উপায় আছে কি? উদাহরণস্বরূপ একটি নাম বা পোস্টকোড
জসন স্ট্যাথাম

36

আপনি এই জাতীয় কোনও অ-সূচকযুক্ত বৈশিষ্ট্যের মধ্যে লুপ করতে পারেন:

var s = new MyObject();
foreach (var p in s.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) {
    Console.WriteLine(p.GetValue(s, null));
}

যেহেতু GetProperties()আয় indexers সেইসাথে সহজ বৈশিষ্ট্য, আপনি কল করার আগে একটি অতিরিক্ত ফিল্টার প্রয়োজন GetValueজানাতে চাই যে, এটা পাস করা নিরাপদ nullদ্বিতীয় প্যারামিটার হিসাবে।

কেবল লেখার জন্য এবং অন্যথায় অ্যাক্সেস অযোগ্য বৈশিষ্ট্যগুলি ছড়িয়ে দেওয়ার জন্য আপনাকে ফিল্টারটি আরও সংশোধন করতে হবে।


প্রকৃতপক্ষে ব্যবহার করা যেতে পারে এমন বৈশিষ্ট্যগুলির সাথে কেবল কিছু করার জন্য +1 - আপনি কেবল লেখার বৈশিষ্ট্যগুলিও ফিল্টার করতে চাইতে পারেন।

@hvd এটি কেবল লেখার বৈশিষ্ট্যগুলিতে একটি দুর্দান্ত পয়েন্ট! আমি তাদের সম্পর্কে প্রায় ভুলে গেছি। আমার কোডটি nullগেটারের সাথে কোনও সম্পত্তির মুখোমুখি হলে ক্র্যাশ হয়ে যাবে তবে আমি নিশ্চিত যে ওপি তার প্রয়োজনীয় বৈশিষ্ট্যগুলি কীভাবে পাবে তা কীভাবে নির্ধারণ করবে।
সের্গেই কালিনিচেনকো

27

আপনার প্রায় সেখানে, সংগ্রহ বা সম্পত্তি ব্যাগ আকারে বৈশিষ্ট্যগুলি অ্যাক্সেসযোগ্য হবে আশা করার পরিবর্তে আপনার কেবল প্রকারের থেকে সম্পত্তিগুলি পাওয়া দরকার:

var property in obj.GetType().GetProperties()

সেখান থেকে আপনি এর মতো অ্যাক্সেস করতে পারেন :

property.Name
property.GetValue(obj, null)

সঙ্গে GetValueযেহেতু একটি স্ট্রিং অক্ষর একটি সংগ্রহ, এছাড়াও আপনি একটি অক্ষর আসতে হলে চাহিদা হতে একটি সূচক উল্লেখ করতে পারেন - দ্বিতীয় প্যারামিটারটি আপনি সূচক মূল্যবোধ, যা বৈশিষ্ট্য সংগ্রহের ফেরার সঙ্গে কাজ করবে উল্লেখ করতে অনুমতি দেবে।


4
আমি কি কাউকে বিচলিত করেছিলাম? আমি এ সম্পর্কে কী জানার জন্য উন্মুক্ত, অন্যথায় আমি কখনও শিখতে পারি না।
গ্রান্ট থমাস

আপনার কোডটি ভুল হলে আপনি সম্ভবত ডাউনটি পেয়েছিলেন (আপনার নিনজা সম্পাদনার আগে)।
রবার্ট হার্ভে

20

অবশ্যই, কোনো সমস্যা নেই:

foreach(object item in sequence)
{
    if (item == null) continue;
    foreach(PropertyInfo property in item.GetType().GetProperties())
    {
        // do something with the property
    }
}

কেন আপনি এই লাইন যুক্ত করেছেন? if (item == null) continue;ব্যক্তিগতভাবে, আমি মনে করি আপনি যদি এই মুহূর্তে কোনও নাল বস্তু পেয়ে থাকেন তবে অনেক আগে কিছু ভুল হয়ে গেছে এবং সেখানেই বৈধতা হওয়া উচিত, বা আমি ভুল করছি?
রাফায়েল হার্সকোভিচি 17

@ ডেমেন্টিক: অবশ্যই, আমরা বলতে পারি যে ক্রমটি নন-নাল রেফারেন্স ধারণ করার জন্য প্রয়োজনীয়।
এরিক লিপার্ট

3

এটি করতে প্রতিবিম্ব ব্যবহার করুন

SomeClass A = SomeClass(...)
PropertyInfo[] properties = A.GetType().GetProperties();

2

আমি এই পৃষ্ঠায় অনুরূপ প্রশ্নের উত্তর খুঁজতে চেয়েছিলাম, আমি বেশ কয়েকটি অনুরূপ প্রশ্নের উত্তর লিখেছিলাম যা এই পৃষ্ঠায় প্রবেশকারী লোকদের সহায়তা করতে পারে।

শ্রেণি তালিকা

তালিকা <টি> শ্রেণি অবজেক্টের তালিকার প্রতিনিধিত্ব করে যা সূচক দ্বারা অ্যাক্সেস করা যায়। এটি সিস্টেম.কলেশন.জেনেরিক নেমস্পেসের আওতায় আসে। তালিকা শ্রেণিটি বিভিন্ন ধরণের যেমন পূর্ণসংখ্যার স্ট্রিং ইত্যাদির সংগ্রহ তৈরি করতে ব্যবহার করা যেতে পারে List তালিকা শ্রেণি তালিকাগুলি অনুসন্ধান, বাছাইকরণ এবং পরিচালনা করার পদ্ধতিও সরবরাহ করে।

সম্পত্তি সহ শ্রেণি :

class TestClss
{
    public string id { set; get; }
    public string cell1 { set; get; }
    public string cell2 { set; get; }
}
var MyArray = new List<TestClss> {
    new TestClss() { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
    new TestClss() { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
    new TestClss() { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" }
};
foreach (object Item in MyArray)
{
    Console.WriteLine("Row Start");
    foreach (PropertyInfo property in Item.GetType().GetProperties())
    {
        var Key = property.Name;
        var Value = property.GetValue(Item, null);
        Console.WriteLine("{0}={1}", Key, Value);
    }
}

অথবা, ক্ষেত্র সহ শ্রেণি :

class TestClss
{
    public string id = "";
    public string cell1 = "";
    public string cell2 = "";
}
var MyArray = new List<TestClss> {
    new TestClss() { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
    new TestClss() { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
    new TestClss() { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" }
};
foreach (object Item in MyArray)
{
    Console.WriteLine("Row Start");
    foreach (var fieldInfo in Item.GetType().GetFields())
    {
        var Key = fieldInfo.Name;
        var Value = fieldInfo.GetValue(Item);
    }

}

বা, অবজেক্টের তালিকা (একই কোষ ব্যতীত):

var MyArray = new List<object> {
    new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
    new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
    new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data", anotherCell = "" }
};
foreach (object Item in MyArray)
{
    Console.WriteLine("Row Start");
    foreach (var props in Item.GetType().GetProperties())
    {
        var Key = props.Name;
        var Value = props.GetMethod.Invoke(Item, null).ToString();
        Console.WriteLine("{0}={1}", Key, Value);
    }
}

বা, অবজেক্টের তালিকা ( এটিতে একই কোষ থাকতে হবে):

var MyArray = new[] {
    new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
    new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
    new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" }
};
foreach (object Item in MyArray)
{
    Console.WriteLine("Row Start");
    foreach (var props in Item.GetType().GetProperties())
    {
        var Key = props.Name;
        var Value = props.GetMethod.Invoke(Item, null).ToString();
        Console.WriteLine("{0}={1}", Key, Value);
    }
}

বা, অবজেক্টের তালিকা (কী সহ):

var MyArray = new {
    row1 = new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
    row2 = new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
    row3 = new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" }
};
// using System.ComponentModel;  for TypeDescriptor
foreach (PropertyDescriptor Item in TypeDescriptor.GetProperties(MyArray))
{
    string Rowkey = Item.Name;
    object RowValue = Item.GetValue(MyArray);
    Console.WriteLine("Row key is: {0}", Rowkey);
    foreach (var props in RowValue.GetType().GetProperties())
    {
        var Key = props.Name;
        var Value = props.GetMethod.Invoke(RowValue, null).ToString();
        Console.WriteLine("{0}={1}", Key, Value);
    }
}

বা, অভিধানের তালিকা

var MyArray = new List<Dictionary<string, string>>() {
    new Dictionary<string, string>() { { "id", "1" }, { "cell1", "cell 1 row 1 Data" }, { "cell2", "cell 2 row 1 Data" } },
    new Dictionary<string, string>() { { "id", "2" }, { "cell1", "cell 1 row 2 Data" }, { "cell2", "cell 2 row 2 Data" } },
    new Dictionary<string, string>() { { "id", "3" }, { "cell1", "cell 1 row 3 Data" }, { "cell2", "cell 2 row 3 Data" } }
};
foreach (Dictionary<string, string> Item in MyArray)
{
    Console.WriteLine("Row Start");
    foreach (KeyValuePair<string, string> props in Item)
    {
        var Key = props.Key;
        var Value = props.Value;
        Console.WriteLine("{0}={1}", Key, Value);
    }
}

শুভকামনা ..


0

একটি ছোট্ট সতর্কতার শব্দ, যদি "কিছু জিনিস করেন" এর অর্থ আপনি যে প্রকৃত সম্পত্তিতে গিয়েছেন তার মূল্য আপডেট করা এবং যদি রুট অবজেক্ট থেকে পরিদর্শন করা সম্পত্তির পথে একটি স্ট্রাক্ট ধরণের সম্পত্তি থাকে তবে সম্পত্তিতে আপনি যে পরিবর্তনটি করেছেন তা হবে মূল অবজেক্টে প্রতিফলিত হবে না।


0

একটি অনুলিপি-পেস্ট সমাধান (এক্সটেনশন পদ্ধতি) বেশিরভাগই এই প্রশ্নের পূর্ববর্তী প্রতিক্রিয়াগুলির ভিত্তিতে।

আইডিসিটিওনারি (ExpandoObject / গতিশীল) সঠিকভাবে পরিচালনা করে যা প্রায়শই এই প্রতিবিম্বিত স্টাফগুলির সাথে কাজ করার সময় প্রয়োজন হয়।

টাইট লুপস এবং অন্যান্য হট পাথগুলিতে ব্যবহারের জন্য প্রস্তাবিত নয়। এই ক্ষেত্রে আপনার কিছু ক্যাচিং / আইএল ইমিট / এক্সপ্রেশন ট্রি সংকলন প্রয়োজন onna

    public static IEnumerable<(string Name, object Value)> GetProperties(this object src)
    {
        if (src is IDictionary<string, object> dictionary)
        {
            return dictionary.Select(x => (x.Key, x.Value));
        }
        return src.GetObjectProperties().Select(x => (x.Name, x.GetValue(src)));
    }

    public static IEnumerable<PropertyInfo> GetObjectProperties(this object src)
    {
        return src.GetType()
            .GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => !p.GetGetMethod().GetParameters().Any());
    }

-1

আমি উপরের কোনও উপায় কাজ করতে পারি না, তবে এটি কাজ করে। ডাইরেক্টরিএন্ট্রির জন্য ব্যবহারকারীর নাম এবং পাসওয়ার্ড alচ্ছিক।

   private List<string> getAnyDirectoryEntryPropertyValue(string userPrincipalName, string propertyToSearchFor)
    {
        List<string> returnValue = new List<string>();
        try
        {
            int index = userPrincipalName.IndexOf("@");
            string originatingServer = userPrincipalName.Remove(0, index + 1);
            string path = "LDAP://" + originatingServer; //+ @"/" + distinguishedName;
            DirectoryEntry objRootDSE = new DirectoryEntry(path, PSUsername, PSPassword);
            var objSearcher = new System.DirectoryServices.DirectorySearcher(objRootDSE);
            objSearcher.Filter = string.Format("(&(UserPrincipalName={0}))", userPrincipalName);
            SearchResultCollection properties = objSearcher.FindAll();

            ResultPropertyValueCollection resPropertyCollection = properties[0].Properties[propertyToSearchFor];
            foreach (string resProperty in resPropertyCollection)
            {
                returnValue.Add(resProperty);
            }
        }
        catch (Exception ex)
        {
            returnValue.Add(ex.Message);
            throw;
        }

        return returnValue;
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.