سؤال

عند استخدام ObsoleteAtribute في .صافي يعطيك مترجم تحذيرات أقول لك أن الكائن/الطريقة/الملكية عفا عليها الزمن شيء آخر ينبغي أن تستخدم.أنا أعمل حاليا على مشروع يتطلب الكثير من إعادة بيع ديون أحد الموظفين السابقين في التعليمات البرمجية.أريد أن أكتب سمة مخصصة التي يمكن استخدامها للاحتفال الأساليب أو الخصائص التي سوف تولد مترجم التحذيرات التي تعطي رسائل أن أكتب.شيء مثل هذا

[MyAttribute("This code sux and should be looked at")]
public void DoEverything()
{
}
<MyAttribute("This code sux and should be looked at")>
Public Sub DoEverything()
End Sub

أريد أن تولد مترجم محذرا من أن يقول: "هذا رمز sux و ينبغي النظر".اعرف كيفية إنشاء سمة مخصصة ، السؤال هو كيف يمكنني يؤدي إلى توليد تحذيرات برنامج التحويل البرمجي visual studio.

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

المحلول

التحديث

هذا هو الممكن الآن مع روزلين (Visual Studio 2015).يمكنك بناء a رمز محلل للتحقق من سمة مخصصة


أنا لا أعتقد أنه من الممكن.ObsoleteAttribute هو معاملة خاصة من قبل المترجم و هو محدد في C# القياسية.لماذا على وجه الأرض هو ObsoleteAttribute غير مقبول ؟ يبدو لي أن هذا هو بالضبط الوضع تم تصميمه و يحقق بالضبط ما تحتاج!

نلاحظ أيضا أن Visual Studio تلتقط التحذيرات التي تم إنشاؤها بواسطة ObsoleteAttribute على الطيران أيضا ، وهو أمر مفيد جدا.

لا أقصد أن يكون غير مفيد, فقط أتساءل لماذا كنت لا تحرص على استخدامه...

للأسف ObsoleteAttribute مختومة (ربما يرجع ذلك جزئيا إلى معاملة خاصة) وبالتالي لا يمكنك فرعية السمة الخاصة بك من ذلك.

من C# القياسية:-

السمة عفا عليها الزمن يتم استخدام علامة أنواع و أعضاء من الأنواع التي يجب أن لم تعد تستخدم.

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

لا أن نلخص الاحتياجات الخاصة بك ؟ ...أنت لن تفعل أفضل من ذلك أنا لا أعتقد.

نصائح أخرى

لا أعرف إذا كان هذا العمل ولكن الأمر يستحق المحاولة.

لا يمكنك تمديد عفا عليها الزمن ، لأن النهائية ، ولكن ربما يمكنك إنشاء الخاصة بك سمة وعلامة تلك الفئة كما عفا عليها الزمن مثل هذا:

[Obsolete("Should be refactored")]
public class MustRefactor: System.Attribute{}

ثم عند علامة الأساليب الخاصة بك مع "MustRefactor" السمة ، ترجمة تحذيرات قد تظهر.

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

التحيات!

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

UPDATE2:مع هذا الرمز فإنه يولد هذه التحذيرات (ليست لطيفة جدا ولكن لا أعتقد أن هناك شيء أفضل).

public class User
{
    private String userName;

    [TooManyArgs] // Will show warning: Try removing some arguments
    public User(String userName)
    {
        this.userName = userName;   
    }

    public String UserName
    {
        get { return userName; }
    }
    [MustRefactor] // will show warning: Refactor is needed Here
    public override string ToString()
    {
        return "User: " + userName;
    }
}
[Obsolete("Refactor is needed Here")]
public class MustRefactor : System.Attribute
{

}
[Obsolete("Try removing some arguments")]
public class TooManyArgs : System.Attribute
{

}

في بعض المجمعين يمكنك استخدام #تحذير إلى إصدار تحذير:

#warning "Do not use ABC, which is deprecated. Use XYZ instead."

في Microsoft المجمعين ، يمكنك عادة استخدام رسالة pragma:

#pragma message ( "text" )

لقد ذكرت .صافي, ولكن لم تحدد ما إذا كنت البرمجة C/C++ أو C#.إذا كنت البرمجة في C#, من يجب أن نعرف أن C# يدعم #تحذير شكل.

نحن الآن في منتصف الكثير من إعادة بيع ديون حيث لم نتمكن من إصلاح كل شيء على الفور.نحن فقط استخدام #تحذير preproc الأمر حيث أننا بحاجة إلى العودة والنظر في التعليمات البرمجية.فإنه يظهر في إخراج المحول البرمجي.أنا لا أعتقد أنه يمكنك وضعه على الطريقة لكن هل يمكن وضعه داخل الطريقة ، فإنه لا يزال من السهل العثور عليها.

public void DoEverything() {
   #warning "This code sucks"
}

في مقابل 2008 (+sp1) #تحذيرات لا تظهر بشكل صحيح في قائمة الأخطاء بعد تنظيف اتصال الآليات & بناء الحل ، أي كل منهم.بعض التحذيرات أظهر في الخطأ قائمة إلا بعد فتح فئة معينة الملف.لذا اضطر إلى استخدام السمة المخصصة:

[Obsolete("Mapping ToDo")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
public class MappingToDo : System.Attribute
{
    public string Comment = "";

    public MappingToDo(string comment)
    {
        Comment = comment;
    }

    public MappingToDo()
    {}
}

لذا عندما علم بعض التعليمات البرمجية مع ذلك

[MappingToDo("Some comment")]
public class MembershipHour : Entity
{
    // .....
}

وتنتج تحذيرات من هذا القبيل:

مساحة الاسم.MappingToDo عفا عليه الزمن:'رسم ما يجب عمله'.

لا أستطيع تغيير نص التحذير ، 'بعض التعليق' ليس أظهرت قائمة الأخطاء.ولكن فإنه سيتم الانتقال إلى المكان المناسب في الملف.حتى إذا كنت تحتاج أن تختلف هذه رسائل التحذير ، إنشاء سمات مختلفة.

ما كنت تحاول القيام به هو إساءة استخدام الصفات.بدلا من استخدام Visual Studio قائمة المهام.يمكنك إدخال التعليقات في التعليمات البرمجية الخاصة بك مثل هذا:

//TODO:  This code sux and should be looked at
public class SuckyClass(){
  //TODO:  Do something really sucky here!
}

ثم فتح عرض / قائمة المهام من القائمة.قائمة المهام قد فئتين ، مهام المستخدم والتعليقات.التبديل إلى التعليقات و سوف ترى كل من //Todo:'s هناك.النقر المزدوج على TODO سيتم الانتقال إلى التعليق في التعليمات البرمجية الخاصة بك.

آل

أنا لا أعتقد أنك يمكن.بقدر ما أعرف دعم ObsoleteAttribute أساسا ضمنية إلى C# compiler;لا يمكنك أن تفعل أي شيء مماثل مباشرة.

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

تبحث في مصدر ObsoleteAttribute, ، فإنه لا يبدو أن تفعل أي شيء خاص لتوليد مترجم سابق إنذار ، لذلك أود أن تميل إلى الذهاب مع @technophile و أقول أنه هو ترميز-الثابت في المترجم.هل هناك سبب لا تريد فقط استخدام ObsoleteAttribute لتوليد تحذير من رسائل ؟

هناك العديد من التعليقات التي تشير إلى إدراج تحذيرات أو pragma.عفا عليها الزمن يعمل بطريقة مختلفة جدا!بمناسبة عفا عليها الزمن دالة من مكتبة L, عفا عليها الزمن رسالة يثير عند برنامج باستدعاء الدالة حتى لو كان المتصل البرنامج ليس في المكتبة L.تحذير يثير الرسالة فقط عندما يتم ترجمة.

هنا هو روزلين التنفيذ ، بحيث يمكنك إنشاء الخاصة بك السمات التي تعطي تحذيرات أو أخطاء على الطاير.

لقد خلق سمة نوع يسمى IdeMessage والتي سوف تكون السمة التي يولد تحذيرات:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class IDEMessageAttribute : Attribute
{
    public string Message;

    public IDEMessageAttribute(string message);
}

من أجل القيام بذلك تحتاج إلى تثبيت روزلين SDK الأولى والبدء من جديد VSIX المشروع مع محلل.لقد حذفت بعض من أقل قطعة ذات الصلة مثل الرسائل, يمكنك معرفة كيفية القيام بذلك.في محلل تفعل هذا

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzerInvocation, SyntaxKind.InvocationExpression);
}

private static void AnalyzerInvocation(SyntaxNodeAnalysisContext context)
{
    var invocation = (InvocationExpressionSyntax)context.Node;

    var methodDeclaration = (context.SemanticModel.GetSymbolInfo(invocation, context.CancellationToken).Symbol as IMethodSymbol);

    //There are several reason why this may be null e.g invoking a delegate
    if (null == methodDeclaration)
    {
        return;
    }

    var methodAttributes = methodDeclaration.GetAttributes();
    var attributeData = methodAttributes.FirstOrDefault(attr => IsIDEMessageAttribute(context.SemanticModel, attr, typeof(IDEMessageAttribute)));
    if(null == attributeData)
    {
        return;
    }

    var message = GetMessage(attributeData); 
    var diagnostic = Diagnostic.Create(Rule, invocation.GetLocation(), methodDeclaration.Name, message);
    context.ReportDiagnostic(diagnostic);
}

static bool IsIDEMessageAttribute(SemanticModel semanticModel, AttributeData attribute, Type desiredAttributeType)
{
    var desiredTypeNamedSymbol = semanticModel.Compilation.GetTypeByMetadataName(desiredAttributeType.FullName);

    var result = attribute.AttributeClass.Equals(desiredTypeNamedSymbol);
    return result;
}

static string GetMessage(AttributeData attribute)
{
    if (attribute.ConstructorArguments.Length < 1)
    {
        return "This method is obsolete";
    }

    return (attribute.ConstructorArguments[0].Value as string);
}

لا توجد CodeFixProvider لهذا يمكنك إزالته من الحل.

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