سؤال

وهذا يؤدي إلى استثناء وقت الترجمة:

public sealed class ValidatesAttribute<T> : Attribute
{

}

[Validates<string>]
public static class StringValidation
{

}

وأنا أدرك C # لا يدعم سمات عامة. ومع ذلك، وبعد الكثير من غوغلينغ، وأنا لا يمكن العثور على ما يبدو السبب.

لا أحد يعرف لماذا الأنواع العامة لا يمكن أن تجنيها من Attribute؟ أي النظريات؟

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

المحلول

حسنا، لا استطيع الاجابة لماذا أنه غير متوفر، ولكن أنا <م> يمكن تأكد من أنها ليست قضية CLI. لا يذكر المواصفات CLI ذلك (بقدر ما أستطيع أن أرى)، وإذا كنت تستخدم IL مباشرة يمكنك إنشاء سمة عامة. من جانب المواصفات C # 3 والتي تحظر ذلك - قسم 10.1.4 "مواصفات قاعدة الطبقة" لا يعطي أي مبرر

ووالمشروح ECMA C # 2 المواصفات لا يعطي أي معلومات مفيدة سواء، على الرغم من أنها لا توفر مثالا على ما لا يسمح.

ونسختي من المشروح C # 3 المواصفات يجب أن تصل غدا ... سوف نرى ما اذا كان يعطي أي مزيد من المعلومات. على أي حال، انها بالتأكيد قرارا لغة بدلا من وقت واحد.

وتحرير: الإجابة من اريك ليبرت (اقتبس): لا يوجد سبب معين، باستثناء لتجنب التعقيد في كل من اللغة ومترجم لحالة الاستخدام والتي لا تضيف قيمة كبيرة

نصائح أخرى

وسمة يزين فئة في الترجمة من الوقت، ولكن فئة عامة لا يتلقى معلوماته نوع النهائية حتى وقت التشغيل. منذ السمة يمكن أن تؤثر على تجميع، بل يجب أن يكون "إكمال" في وقت الترجمة.

MSDN المقالة لمزيد من المعلومات.

وأنا لا أعرف لماذا هذا غير مسموح به، ولكن هذا هو الحل الممكن واحد

[AttributeUsage(AttributeTargets.Class)]
public class ClassDescriptionAttribute : Attribute
{
    public ClassDescriptionAttribute(Type KeyDataType)
    {
        _KeyDataType = KeyDataType;
    }

    public Type KeyDataType
    {
        get { return _KeyDataType; }
    }
    private Type _KeyDataType;
}


[ClassDescriptionAttribute(typeof(string))]
class Program
{
    ....
}

وهذا ليس حقا عام ولا يزال لديك لكتابة الطبقة سمة محددة لكل نوع، ولكن قد تكون قادرا على استخدام واجهة قاعدة عامة لرمز قليلا دفاعية، كتابة التعليمات البرمجية أقل من المطلوب على خلاف ذلك، والحصول على فوائد تعدد الأشكال الخ

//an interface which means it can't have its own implementation. 
//You might need to use extension methods on this interface for that.
public interface ValidatesAttribute<T>
{
    T Value { get; } //or whatever that is
    bool IsValid { get; } //etc
}

public class ValidatesStringAttribute : Attribute, ValidatesAttribute<string>
{
    //...
}
public class ValidatesIntAttribute : Attribute, ValidatesAttribute<int>
{
    //...
}

[ValidatesString]
public static class StringValidation
{

}
[ValidatesInt]
public static class IntValidation
{

}

وهذا هو سؤال جيد جدا. في تجربتي مع الصفات، وأعتقد أن القيد في المكان لأنه عندما يعكس على سمة فإنه خلق حالة التي سيكون لديك للتحقق من كل التباديل الممكنة نوع: typeof(Validates<string>)، typeof(Validates<SomeCustomType>)، الخ ...

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

ولعل فئة التحقق من صحة أن يأخذ في SomeCustomValidationDelegate أو ISomeCustomValidator كمعلمة أن يكون نهجا أفضل.

وبلدي الحل هو شيء من هذا القبيل:

public class DistinctType1IdValidation : ValidationAttribute
{
    private readonly DistinctValidator<Type1> validator;

    public DistinctIdValidation()
    {
        validator = new DistinctValidator<Type1>(x=>x.Id);
    }

    public override bool IsValid(object value)
    {
        return validator.IsValid(value);
    }
}

public class DistinctType2NameValidation : ValidationAttribute
{
    private readonly DistinctValidator<Type2> validator;

    public DistinctType2NameValidation()
    {
        validator = new DistinctValidator<Type2>(x=>x.Name);
    }

    public override bool IsValid(object value)
    {
        return validator.IsValid(value);
    }
}

...
[DataMember, DistinctType1IdValidation ]
public Type1[] Items { get; set; }

[DataMember, DistinctType2NameValidation ]
public Type2[] Items { get; set; }

وهذا غير موجود حاليا ميزة C # لغة، ولكن هناك الكثير من النقاش على C # لغة رسمية الريبو .

بعض الملاحظات اجتماع :

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

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

     

ونحن بحاجة إلى آلية لفهم أي استهداف وقت التشغيل يعمل على. نحن   نحتاج الى ذلك أشياء كثيرة، ونبحث حاليا في ذلك. حتى   ثم، ونحن لا يمكن أن أعتبر.

     

والمرشح لرئيسي C # نسخة، إذا يمكننا أن نجعل عدد كاف   من وقت التشغيل إصدارات التعامل معها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top