কীভাবে ব্যবহারযোগ্য .NET প্রতিবিম্ব নালযোগ্য রেফারেন্স ধরণের জন্য চেক করতে


15

সি # 8.0 অযোগ্য রেফারেন্স ধরণের প্রবর্তন করে। এখানে একটি অযোগ্য সম্পত্তি সহ একটি সাধারণ বর্গ:

public class Foo
{
    public String? Bar { get; set; }
}

কোনও শ্রেণীর সম্পত্তি কীভাবে প্রতিবিম্বের মাধ্যমে একটি অযোগ্য রেফারেন্স টাইপ ব্যবহার করে তা পরীক্ষা করার কোনও উপায় আছে?


সংকলন এবং আইএল দিকে তাকিয়ে, দেখে মনে হচ্ছে এই যোগ মত [NullableContext(2), Nullable((byte) 0)]করতে টাইপ ( Foo) - সুতরাং যে কি জন্য চেক করতে, কিন্তু আমি ব্যাখ্যা করতে কিভাবে যে নিয়ম বুঝতে আরো খনন প্রয়োজন চাই এর!
মার্ক Gravell

4
হ্যাঁ, তবে এটি তুচ্ছ নয়। ভাগ্যক্রমে, এটি করা হয় নথিভুক্ত
জেরোইন মোস্টার্ট

আহ আমি দেখি; তাই string? Xকোন বৈশিষ্ট্যাবলী পায়, এবং string Yপায় [Nullable((byte)2)]সঙ্গে [NullableContext(2)]accessors উপর
মার্ক Gravell

1
যদি কোনও প্রকারের মধ্যে কেবলমাত্র নলযোগ্য (বা অ-অযোগ্য) থাকে তবে এগুলি সমস্তই প্রতিনিধিত্ব করে NullableContext। যদি একটি মিশ্রণ থাকে, তবে Nullableপাশাপাশি ব্যবহার করা হবে। NullableContextচেষ্টা করা এবং Nullableসমস্ত জায়গাতেই নির্গত হওয়া এড়ানো একটি অপ্টিমাইজেশন ।
ক্যান্টন 7

উত্তর:


11

কমপক্ষে আমি যে ধরণের পরীক্ষার সাথে এটি পরীক্ষা করেছি সেগুলি নিয়ে এটি কাজ করে বলে মনে হচ্ছে।

আপনি পাস প্রয়োজন PropertyInfoসম্পত্তি আপনি আগ্রহী জন্য, এবং এছাড়াও Typeযা সম্পত্তি সংজ্ঞায়িত করা হয় ( না একটি উদ্ভূত বা অভিভাবক টাইপ - এটা সঠিক টাইপ হতে হয়েছে):

public static bool IsNullable(Type enclosingType, PropertyInfo property)
{
    if (!enclosingType.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Contains(property))
        throw new ArgumentException("enclosingType must be the type which defines property");

    var nullable = property.CustomAttributes
        .FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute");
    if (nullable != null && nullable.ConstructorArguments.Count == 1)
    {
        var attributeArgument = nullable.ConstructorArguments[0];
        if (attributeArgument.ArgumentType == typeof(byte[]))
        {
            var args = (ReadOnlyCollection<CustomAttributeTypedArgument>)attributeArgument.Value;
            if (args.Count > 0 && args[0].ArgumentType == typeof(byte))
            {
                return (byte)args[0].Value == 2;
            }
        }
        else if (attributeArgument.ArgumentType == typeof(byte))
        {
            return (byte)attributeArgument.Value == 2;
        }
    }

    var context = enclosingType.CustomAttributes
        .FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute");
    if (context != null &&
        context.ConstructorArguments.Count == 1 &&
        context.ConstructorArguments[0].ArgumentType == typeof(byte))
    {
        return (byte)context.ConstructorArguments[0].Value == 2;
    }

    // Couldn't find a suitable attribute
    return false;
}

বিশদ জন্য এই নথিটি দেখুন ।

সাধারণ বক্তব্যটি হ'ল হয় নিজেই সম্পত্তিটির [Nullable]উপর তার কোনও বৈশিষ্ট্য থাকতে পারে, অথবা এটি যদি সংযুক্তকরণের ধরণের [NullableContext]বৈশিষ্ট্য নাও রাখতে পারে । আমরা প্রথমে সন্ধান করি [Nullable], তারপরে যদি এটি না পাওয়া যায় তবে আমরা [NullableContext]ঘেরের ধরণটি অনুসন্ধান করি ।

সংকলকটি অ্যাসেমব্লিতে বৈশিষ্ট্যগুলি এম্বেড করতে পারে এবং যেহেতু আমরা অন্য কোনও সমাবেশ থেকে কোনও ধরণের দিকে চেয়ে থাকি, তাই আমাদের কেবল প্রতিবিম্ব-লোড করা দরকার।

[Nullable]সম্পত্তি জেনারিক হলে একটি অ্যারে দিয়ে ইনস্ট্যান্টিয়েট করা হতে পারে। এই ক্ষেত্রে, প্রথম উপাদানটি প্রকৃত সম্পত্তিকে উপস্থাপন করে (এবং আরও উপাদানগুলি জেনেরিক যুক্তি উপস্থাপন করে)। [NullableContext]সর্বদা একক বাইট দ্বারা তাত্ক্ষণিক হয়।

2"Nullaable" এর অর্থ একটি মান । 1এর অর্থ "অযোগ্য নয়", এবং এর 0অর্থ "বিস্মৃত"।


এটা সত্যিই কৃপণ। আমি সবেমাত্র একটি ব্যবহারের কেস পেয়েছি যা এই কোড দ্বারা আওতায় নেই। পাবলিক ইন্টারফেস IBusinessRelation : ICommon {}/ public interface ICommon { string? Name {get;set;} }। আমি যদি IBusinessRelationসম্পত্তিটির সাথে পদ্ধতিটি কল করি তবে আমি Nameমিথ্যা হয়ে যাব।
gsharp

@ শার্ফ আহ, আমি ইন্টারফেস বা কোনও ধরণের উত্তরাধিকারের সাথে চেষ্টা করে দেখিনি। আমি অনুমান করছি এটি একটি অপেক্ষাকৃত সহজ ফিক্স (বেস ইন্টারফেস থেকে প্রসঙ্গ বৈশিষ্ট্যগুলি দেখুন): আমি চেষ্টা করব এবং পরে এটি ঠিক করব
ক্যান্টন 7

1
বড় কথা না আমি শুধু এটি উল্লেখ করতে চেয়েছিলেন। এই অবিস্মরণীয় জিনিসগুলি আমাকে পাগল করছে ;-)
gsharp

1
@gsharp এটিকে দেখার জন্য, আপনাকে সেই ধরণের ইন্টারফেসটি পাস করতে হবে যা সম্পত্তিটি সংজ্ঞায়িত করে - যা তা ICommonনয় IBusinessRelation। প্রতিটি ইন্টারফেস তার নিজস্ব সংজ্ঞা দেয় NullableContext। আমি আমার উত্তরটি পরিষ্কার করে দিয়েছি এবং এর জন্য একটি রানটাইম চেক যুক্ত করেছি।
ক্যান্টন 7
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.