سؤال

وحصلت نفسي في الحالة التي يكون فيها استخدام بدت الطبقة System.Attribute (للوهلة الأولى) ليكون فكرة جيدة.

ولدي كائن التي سيتم طباعتها في طلبي، وأنا بحاجة إلى التسمية قبل كل الممتلكات (أو مجرد سلسلة قبل ذلك). يمكن أن أضع كل الممتلكات ضمنية مثل:

Console.WriteLine("Color:"+obj.color);
Console.WriteLine("Size:"+obj.size);

وهلم جرا لكل الممتلكات. ولكن بدلا من ذلك، كنت أحاول أن إنشاء التعليمات البرمجية حيث لا يحتاج هذا 'التسمية' أن ضمنية، حتى أتمكن من طباعة كل الممتلكات بشكل حيوي.

وحصلت على شيء من هذا القبيل، وذلك باستخدام الطبقة System.Attribute:

public class MyObject 
{
    [MyCustomLabel("Color:")]
    public string Color;

    [MyCustomLabel("Size:")]
    public string Size;
    //etc...
}

وحتى هنا يأتي مشكلتي: استرجاع قيمة هذه السمة ليست مستحيلة، ولكنها ليست ودية منذ اضطررت لاستخدام بعض انعكاس لذلك.

وأنا لست خائفا حقا استخدام التفكير، ولكن يبدو أن كنت تستخدم سمات عن شيء لم تنشأ من أجله.

وأتساءل أين هي أفضل الأماكن لاستخدام السمات، وإذا كان هذا هو حقا موقف لاستخدامه.

هل كانت مفيدة؟

المحلول

وسمات والتفكير يسيران جنبا إلى جنب. باستثناء بعض سمات مترجم / وقت التشغيل، وليس هناك وسيلة لاستخدامها مع خروج يعكس مدى التعليمات البرمجية.

وقال ان النهج الخاص بك هو معقول، وكنت قد ترغب في إلقاء نظرة على السمات في مساحة الاسم System.ComponentModel التي لديها عدد من الطبقات لتزيين الخصائص مع الفوقية مفيد.

نصائح أخرى

وأنت على الطريق الصحيح.

وأيضا، هناك سمة [اسم العرض] بالفعل مصممة خصيصا لهذا الغرض، والتي كانت في. NET منذ 2.0.

http://msdn.microsoft.com/en -US / مكتبة / system.componentmodel.displaynameattribute.aspx

إذا كنت مجرد الكتابة إلى وحدة، أي انها التصحيح الانتاج أسلوب ثم ما تريده هو فرصة الحد الأدنى من خطأ مطبعي لصق / نسخ.

وهذا هو الخلط تحت غطاء محرك السيارة ولكن غير فعالة للغاية في مواقع المكالمة:

public static void WriteNameAndValue<T,TValue>(
    this TextWriter tw, T t,
    Expression<Func<T, TValue>> getter)
{
    var memberExpression = getter.Body as MemberExpression;
    if (memberExpression == null)
        throw new ArgumentException("missing body!");
    var member = memberExpression.Member;
    tw.Write(member.Name);
    tw.Write(": ");
    if (member is FieldInfo)
    {
        tw.Write(((FieldInfo)member).GetValue(t));
    }
    else if (member is PropertyInfo)
    {
        tw.Write(((PropertyInfo)member).GetValue(t, null));
    }
}


public static void WriteNameAndValueLine<T,TValue>(
    this TextWriter tw, T t,
    Expression<Func<T, TValue>> getter)
{

    WriteNameAndValue<T,TValue>(tw, t, getter);
    tw.WriteLine();
}

وبعد ذلك يمكنك كتابة

t.Foo = "bar";
t.Bar = 32.5;
Console.Out.WriteNameAndValueLine(t, x => x.Foo);
Console.Out.WriteNameAndValueLine(t, x => x.Bar);
// output
// Foo: bar
// Bar: 32.5

إذا كنت تريد أن يكون أكثر شكلي في وقت التشغيل عن طريق الموارد ومع الاعتبارات لتوطين يمكنك القيام بذلك ولكن أود أن تنظر أخرى أكثر توحيدا، النهج، بدلا من ذلك إذا كان هذا الشرط احتمالا.

وP.S. إذا أردت الحصول على الهوى هل يمكن أن يحل محل التبديل FieldInfo / PropertyInfo مع

tw.Write(getter.Compile()(t));

وبعد ذلك يمكن التحقق من وجود MethodInfo في التعبير وكذلك (أو السماح lambdas التعسفية وفقط ضع رقم السطر أو بعض النصوص عامة أخرى. أقترح عدم نزول هذا الطريق، واستخدام مربكة بالفعل أيضا هذا قد يتسبب غير المرغوب فيها تحميل في ما ينبغي أن تكون طريقة تسجيل بسيط.

وهذا هو بالضبط كيف يعمل التسلسل ذلك أود أن أقول نهجكم معقول. وهناك طريقة أخرى يمكنك التعامل مع هذا هي لإنشاء معجم PropertyNames والعناوين وثم البحث عن عنوان استنادا إلى اسم الممتلكات.

<اقتباس فقرة>   <اقتباس فقرة>     

ولدي الكائن المراد طباعتها في طلبي، وأنا بحاجة إلى التسمية قبل كل الممتلكات (أو مجرد سلسلة قبل ذلك).

  

وماذا يفكرون في استخدام الصفات في قضيتك؟ أين قمت بطباعة هذه الكائنات في التطبيق الخاص بك.

وربما مجرد تطبيق على ToString في وجوه الخاص بك (ق)
منها مثلا.

public override string ToString()
{
    StringBuilder sb = new StringBuilder();

    sb.Append("PropertyX: ");
    sb.AppendLine(this.PropertyX);

    // get string from resource file
    sb.Append(Resources.FileName);
    sb.Append(": ");
    sb.AppendLine(this.FileName);

    sb.Append("Number: ");
    sb.AppendLine(this.Number.ToString());

    return sb.ToString();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top