当在.NET中使用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的,应被看作”。 我知道如何创建一个自定义属性,问题是我如何使它产生视觉工作室编译器警告。
Answer 1:
更新
这是现在可以与罗斯林(Visual Studio中2015年)。 你可以建立一个代码分析器来检查自定义属性
我不相信这是可能的。 ObsoleteAttribute是由编译器特殊处理和在C#标准被定义。 到底是什么原因ObsoleteAttribute不能接受? 在我看来,像这也正是它被设计的局面,并精确地达到您所需要的!
还要注意的是Visual Studio中拿起在飞行中通过ObsoleteAttribute产生的警告过,这是非常有用的。
不要吝啬是无益的,只是想知道为什么你不热衷于使用它...
不幸的是ObsoleteAttribute密封(可能部分是由于特殊处理),因此你不能从它继承自己的属性。
从C#标准: -
过时属性用于标记的类型和不应该再使用类型的成员。
如果程序使用装饰有过时的属性类型或成员,则编译器将发出警告或错误信息。 具体而言,编译器会发出警告,如果没有错误的参数设置,或者如果提供了错误的参数,其值为假。 编译器问题如果指定了错误的参数错误,值为true。
那岂不是总结您的需求?......你不会做的比我不觉得更好。
Answer 2:
不知道这是否会工作,但它是值得一试。
不能扩展过时,因为它的最后,但也许你可以创建自己的属性,并标记类为过时的是这样的:
[Obsolete("Should be refactored")]
public class MustRefactor: System.Attribute{}
然后,当你标记的“MustRefactor”属性的方法,编译警告可能会显示。
我说:“也许”和“可能”,是因为我没有尝试这样做。 请告诉我,如果它不工作,所以我就删除了答案。
问候!
UPDATE:测试它。 它会产生一个编译时警告,但错误信息看起来很滑稽,你应该看到它为自己和选择。 这是非常接近你想要达到的目标。
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
{
}
Answer 3:
在一些编译器可以使用#warning后发出警告:
#warning "Do not use ABC, which is deprecated. Use XYZ instead."
在微软的编译器,你可以用通常的消息编译:
#pragma message ( "text" )
你提到的.Net,但没有说明是否你用C / C ++或C#编程。 如果你在C#编程,比你应该知道, C#支持#warning后的格式 。
Answer 4:
目前,我们正处在一个大量的重构,我们不可能解决所有问题马上的中间。 我们只需要使用#warning后preproc命令,我们需要回去看看代码。 它显示了在编译器输出。 我不认为你可以把它放在一个方法,但你可以把它只是方法里面,它仍然很容易找到。
public void DoEverything() {
#warning "This code sucks"
}
Answer 5:
2008年,VS(+ SP1)#warnings不正确的错误列表显示后清洁Soultion与重建解决方案,没有所有的人。 一些警告将显示在后,才打开特定的类文件中的错误列表。 所以,我被迫使用自定义属性:
[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
{
// .....
}
它产生这样的警告:
Namespace.MappingToDo是过时:“映射待办事项”。
我不能改变的警语的文字,“有些评论”是不是表明,它错误列表。 但它会跳转到正确的位置在文件中。 所以,如果你需要改变这样的警告信息,创建各种属性。
Answer 6:
你所要做的是属性的误用。 相反,使用Visual Studio任务列表。 您可以输入您的代码中像这样的评论:
//TODO: This code sux and should be looked at
public class SuckyClass(){
//TODO: Do something really sucky here!
}
然后从菜单中打开查看/任务列表。 任务列表有两大类,用户的任务和评论。 切换到评论,你会看到所有//待做事项的:“在那儿。 在TODO双击就会跳转到代码中的注释。
人
Answer 7:
我不认为你可以。 据我知道ObsoleteAttribute支持基本上是硬编码到C#编译器; 你不能直接做类似的事情。
你也许能够做的是使用执行对刚刚编译的程序集的自定义工具的MSBuild任务(或生成后事件)。 自定义工具将反映在装配中的所有类型/方法和消耗你的自定义属性,此时它可以打印到System.Console的默认或错误TextWriters。
Answer 8:
纵观源ObsoleteAttribute ,它看起来并不像它做什么特别的生成编译器警告,所以我会倾向于去@ 让技术和说,这是硬编码到编译器。 你有什么不想只用一个理由ObsoleteAttribute产生的警告消息?
Answer 9:
有一些意见是建议插入警告或编译。 过时的作品在一个非常不同的方式! 标记库升过时的功能,当程序调用,即使调用者程序是不是在图书馆L.警告引发只有当L被编译消息的功能过时的消息引发。
Answer 10:
这里是罗斯林实施,这样你就可以创建自己的属性,让在飞行警告或错误。
我已经创建称为属性类型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为此,你可以从溶液中取出。
文章来源: Custom Compiler Warnings