সম্পত্তির গুণাবলী আছে কিনা তা পরীক্ষা করুন


158

কোনও শ্রেণিতে একটি বৈশিষ্ট্য সহ বৈশিষ্ট্যযুক্ত সম্পত্তি দেওয়া হয়েছে - প্রদত্ত বৈশিষ্ট্য রয়েছে কিনা তা নির্ধারণের দ্রুততম উপায় কী? উদাহরণ স্বরূপ:

    [IsNotNullable]
    [IsPK]
    [IsIdentity]
    [SequenceNameAttribute("Id")]
    public Int32 Id
    {
        get
        {
            return _Id;
        }
        set
        {
            _Id = value;
        }
    }

উদাহরণস্বরূপ এটির "ইসআইডেন্টিটি" বৈশিষ্ট্য রয়েছে তা নির্ধারণের জন্য দ্রুততম পদ্ধতিটি কী?

উত্তর:


279

গুণাবলী পুনরুদ্ধার করার কোনও দ্রুত উপায় নেই। তবে কোডটি দেখতে এইরকম হওয়া উচিত ( অ্যারোনআউটকে কৃতিত্ব ):

var t = typeof(YourClass);
var pi = t.GetProperty("Id");
var hasIsIdentity = Attribute.IsDefined(pi, typeof(IsIdentity));

আপনি যদি বৈশিষ্ট্য বৈশিষ্ট্য পুনরুদ্ধার প্রয়োজন হয়

var t = typeof(YourClass);
var pi = t.GetProperty("Id");
var attr = (IsIdentity[])pi.GetCustomAttributes(typeof(IsIdentity), false);
if (attr.Length > 0) {
    // Use attr[0], you'll need foreach on attr if MultiUse is true
}

63
আপনার যদি কেবল অ্যাট্রিবিউটটির অস্তিত্বের জন্য পরীক্ষা করতে হবে এবং এর থেকে কোনও তথ্য উদ্ধার না করে ব্যবহার করে Attribute.IsDefinedকোডের একটি লাইন এবং কুৎসিত অ্যারে / ingালাই মুছে ফেলা হবে।
অ্যারোনআট

4
আমি যা এটিকে দিয়ে চলেছি তার মধ্যে কিছু বৈশিষ্ট্যের আলাদা আলাদা আলাদা বৈশিষ্ট্য রয়েছে ute উদাহরণস্বরূপ "NotMapped" System.ComponentModel.DataAnnotations.Schema ব্যবহার করা হয় যেমন [NotMapped]আপনি ব্যবহার করতে হবে ক্লাসে কিন্তু এটি সনাক্ত করতেAttribute.IsDefined(pi, typeof(NotMappedAttribute))
Qjimbo

2
জেনেরিক ওভারলোডটি ব্যবহার করা সহজ হতে পারে:IsIdentity[] attr = pi.GetCustomAttributes<IsIdentity>(false);
মোজতাবা

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

44

যদি আপনি .NET 3.5 ব্যবহার করে থাকেন তবে আপনি এক্সপ্রেশন ট্রি দিয়ে চেষ্টা করতে পারেন। এটি প্রতিবিম্বের চেয়ে নিরাপদ:

class CustomAttribute : Attribute { }

class Program
{
    [Custom]
    public int Id { get; set; }

    static void Main()
    {
        Expression<Func<Program, int>> expression = p => p.Id;
        var memberExpression = (MemberExpression)expression.Body;
        bool hasCustomAttribute = memberExpression
            .Member
            .GetCustomAttributes(typeof(CustomAttribute), false).Length > 0;
    }
}

7
FYI আপনার উত্তর সম্পর্কে একটি প্রশ্ন জিজ্ঞাসা করা হয়েছে। stackoverflow.com/questions/4158996/…
গ্রেগ

12

আপনি প্রদত্ত মেম্বার ইনফোতে অ্যাট্রিবিউট পড়তে একটি সাধারণ (জেনেরিক) পদ্ধতি ব্যবহার করতে পারেন

public static bool TryGetAttribute<T>(MemberInfo memberInfo, out T customAttribute) where T: Attribute {
                var attributes = memberInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault();
                if (attributes == null) {
                    customAttribute = null;
                    return false;
                }
                customAttribute = (T)attributes;
                return true;
            }

7

@ હંস প্যাস্যান্ট দ্বারা উত্তর আপডেট এবং / বা উন্নত করতে আমি সম্পত্তি পুনরুদ্ধারকে একটি এক্সটেনশন পদ্ধতিতে পৃথক করব। এটি getProperty পদ্ধতিতে কদর্য জাদু স্ট্রিং অপসারণ করার অতিরিক্ত সুবিধা রয়েছে

public static class PropertyHelper<T>
{
    public static PropertyInfo GetProperty<TValue>(
        Expression<Func<T, TValue>> selector)
    {
        Expression body = selector;
        if (body is LambdaExpression)
        {
            body = ((LambdaExpression)body).Body;
        }
        switch (body.NodeType)
        {
            case ExpressionType.MemberAccess:
                return (PropertyInfo)((MemberExpression)body).Member;
            default:
                throw new InvalidOperationException();
        }
    }
}

আপনার পরীক্ষাটি তখন দুটি লাইনে হ্রাস পেয়েছে

var property = PropertyHelper<MyClass>.GetProperty(x => x.MyProperty);
Attribute.IsDefined(property, typeof(MyPropertyAttribute));

7

আপনি যদি পোর্টেবল ক্লাস লাইব্রেরি পিসিএলে (আমার মতো) এটি করার চেষ্টা করে থাকেন তবে আপনি কীভাবে এটি করতে পারেন তা এখানে রয়েছে :)

public class Foo
{
   public string A {get;set;}

   [Special]
   public string B {get;set;}   
}

var type = typeof(Foo);

var specialProperties = type.GetRuntimeProperties()
     .Where(pi => pi.PropertyType == typeof (string) 
      && pi.GetCustomAttributes<Special>(true).Any());

তারপরে আপনার প্রয়োজন অনুসারে এই বিশেষ সম্পত্তি রয়েছে এমন সংখ্যার যাচাই করতে পারেন।


7

এটি এখন নতুন সি # বৈশিষ্ট্যটির nameof()মতো নিরাপদ পদ্ধতিতে এক্সপ্রেশন ট্রি এবং এক্সটেনশন পদ্ধতি ছাড়াই করা যেতে পারে :

Attribute.IsDefined(typeof(YourClass).GetProperty(nameof(YourClass.Id)), typeof(IsIdentity));

নামফ () সি # 6 তে প্রবর্তিত হয়েছিল


6

আপনি এট্রিবিউট.আইএসডিফাইন্ড পদ্ধতিটি ব্যবহার করতে পারেন

https://msdn.microsoft.com/en-us/library/system.attribute.isdefined(v=vs.110).aspx

if(Attribute.IsDefined(YourProperty,typeof(YourAttribute)))
{
    //Conditional execution...
}

আপনি যে সম্পত্তিটি বিশেষভাবে সন্ধান করছেন তা সরবরাহ করতে পারেন বা প্রতিচ্ছবি ব্যবহার করে আপনি সেগুলি দিয়ে পুনরাবৃত্তি করতে পারেন, এরকম কিছু:

PropertyInfo[] props = typeof(YourClass).GetProperties();

এটি সংকলন করে না। আপনি ব্যবহার করতে পারবেন না [] YourProperty বা YourAttribute প্রায়
ছুয়ে

পূর্ববর্তী প্রতিটি উত্তরে শ্রেণি, সম্পত্তি এবং বৈশিষ্ট্যর নামগুলির উপর অনুমানগুলি ব্যবহার করা হয়েছে যা আমি অনুসরণ করেছি।
ফ্রান্সিস মুসিগানাক

উপস্থিত এখন স্থির।
রোলগুলি

2

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

আমার পদ্ধতিতে এই প্যারামিটারটি রয়েছে তবে এটি নির্মিত হতে পারে:

Expression<Func<TModel, TValue>> expression

তারপরে পদ্ধতিতে এটি:

System.Linq.Expressions.MemberExpression memberExpression 
       = expression.Body as System.Linq.Expressions.MemberExpression;
Boolean hasIdentityAttr = System.Attribute
       .IsDefined(memberExpression.Member, typeof(IsIdentity));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.