আমি প্রতিবিম্ব দ্বারা একটি ধরণের সমস্ত ধ্রুবক কীভাবে পেতে পারি?


উত্তর:


264

যদিও এটি একটি পুরানো কোড:

private FieldInfo[] GetConstants(System.Type type)
{
    ArrayList constants = new ArrayList();

    FieldInfo[] fieldInfos = type.GetFields(
        // Gets all public and static fields

        BindingFlags.Public | BindingFlags.Static | 
        // This tells it to get the fields from all base types as well

        BindingFlags.FlattenHierarchy);

    // Go through the list and only pick out the constants
    foreach(FieldInfo fi in fieldInfos)
        // IsLiteral determines if its value is written at 
        //   compile time and not changeable
        // IsInitOnly determines if the field can be set 
        //   in the body of the constructor
        // for C# a field which is readonly keyword would have both true 
        //   but a const field would have only IsLiteral equal to true
        if(fi.IsLiteral && !fi.IsInitOnly)
            constants.Add(fi);           

    // Return an array of FieldInfos
    return (FieldInfo[])constants.ToArray(typeof(FieldInfo));
}

উৎস

জেনেরিকস এবং লিনকিউ ব্যবহার করে আপনি সহজেই এটিকে ক্লিনার কোডে রূপান্তর করতে পারেন:

private List<FieldInfo> GetConstants(Type type)
{
    FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Public |
         BindingFlags.Static | BindingFlags.FlattenHierarchy);

    return fieldInfos.Where(fi => fi.IsLiteral && !fi.IsInitOnly).ToList();
}

অথবা একটি লাইন সহ:

type.GetFields(BindingFlags.Public | BindingFlags.Static |
               BindingFlags.FlattenHierarchy)
    .Where(fi => fi.IsLiteral && !fi.IsInitOnly).ToList();

13
আমার +1টি আমি ২ য় লাইন পেরোনোর ​​আগেই ছিলাম .. আমি লক্ষ্য করেছি আপনি প্রতিটি ধাপে এর ... উদ্দেশ্য অনুসারে ডিজাইন উদ্দেশ্য নিয়ে যাচ্ছেন ...! এই হল তাই গুরুত্বপূর্ণ যখন কেউ তা থেকে শিক্ষা নিতে হবে। আমি আশা করি আপনার অভিজ্ঞতার সাথে প্রত্যেকে এখানে যেমন করেছেন তেমন করুন।
লোনএক্সকোডার

4
ইসলিটরাল এবং ইসআইনিটঅনলি সম্পর্কিত শ্রম সম্পর্কে আমি নিশ্চিত নই। পরীক্ষার সময় মনে হয় স্থির পাঠযোগ্য মাত্রার জন্য ইসলিটারাল সর্বদা মিথ্যা - সুতরাং ইসলিটরালই কেবলমাত্র ধনাত্মক সন্ধানের জন্য যাচাই করা উচিত এবং আপনি ইসলিটনালি উপেক্ষা করতে পারেন। আমি বিভিন্ন ক্ষেত্রের প্রকারের (উদাহরণস্বরূপ স্ট্রিং, ইন্ট 32) দিয়ে চেষ্টা করে দেখেছি যে এটি কোনও পার্থক্য করেছে কিনা তবে তা কার্যকর হয়নি।
মার্ক ওয়াটস

49
এছাড়াও, FieldInfo থেকে কনস্টের মান পেতে, getRawConstantValue () ব্যবহার করুন।
স্যাম সিপ্প

@ মার্কওয়াটস ঠিক আছে। এটি পোস্ট হওয়ার পরে আচরণের পরিবর্তন হতে পারে। যে কোনও ক্ষেত্রে ডকুমেন্টেশন IsLiteralবলেছেন if its value is written at compile timeএবং এটি কেবল
ধ্রুবকদের

52

আপনি যদি লক্ষ্য ধরণের থেকে কোনও নির্দিষ্ট ধরণের সমস্ত স্থির মান পেতে চান তবে এখানে একটি এক্সটেনশন পদ্ধতি (এই পৃষ্ঠার উত্তরগুলির কয়েকটি প্রসারিত করা):

public static class TypeUtilities
{
    public static List<T> GetAllPublicConstantValues<T>(this Type type)
    {
        return type
            .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
            .Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(T))
            .Select(x => (T)x.GetRawConstantValue())
            .ToList();
    }
}

তারপর এই মত একটি শ্রেণীর জন্য

static class MyFruitKeys
{
    public const string Apple = "apple";
    public const string Plum = "plum";
    public const string Peach = "peach";
    public const int WillNotBeIncluded = -1;
}

আপনি এর stringমতো ধ্রুবক মানগুলি পেতে পারেন:

List<string> result = typeof(MyFruitKeys).GetAllPublicConstantValues<string>();
//result[0] == "apple"
//result[1] == "plum"
//result[2] == "peach"

কেন নয় এই: .Where(fi => fi.IsLiteral && !fi.IsInitOnly).Select(x => x.GetRawConstantValue()).OfType<T>().ToList();?
টি-মোটি

17

প্রকারের এক্সটেনশন হিসাবে:

public static class TypeExtensions
{
    public static IEnumerable<FieldInfo> GetConstants(this Type type)
    {
        var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);

        return fieldInfos.Where(fi => fi.IsLiteral && !fi.IsInitOnly);
    }

    public static IEnumerable<T> GetConstantsValues<T>(this Type type) where T : class
    {
        var fieldInfos = GetConstants(type);

        return fieldInfos.Select(fi => fi.GetRawConstantValue() as T);
    }
}

1
স্পষ্টতই এটি হ'ল যদি কোনও ধরণের আপনার ধ্রুবকগুলি সমস্ত স্ট্রিং হয় ;-)
বাইটেডেভ

(ক) পদ্ধতিগুলি জেনেরিক করে না কেন, (খ) পদ্ধতিগুলি IEnumerable<T>পরিবর্তে পরিবর্তিত করে IList?
ওয়াই হা লি

@ ওয়াইএইলি - সম্পন্ন :-)- যদিও স্পষ্টতই এটি এখনও ধরে নেওয়া হয়েছে যে প্রশ্নে ক্লাসে সমস্ত ধরণের কনসেট রয়েছে তা টাইপ টি
বাইটেদেব

2

property.GetConstantValue()মান পেতে ব্যবহার করুন ।


1
আপনার সম্পত্তি আছে যখন এটি ক্ষেত্রে ভাল হতে পারে - কিন্তু আপনি প্রথম সম্পত্তি পেতে কিভাবে ?
ওয়াই হা লি

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