谁能说出这个Syntax类的命名空间?
我已经通过nuget安装了所有roslyn包,但我不知道用于创建表达式语法对象的静态工厂方法的名称空间.
Web上的许多Roslyn示例都使用这些命名空间
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
Run Code Online (Sandbox Code Playgroud)
现在这些已经过时了吗?我使用以下内容
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下这个区别吗?
我有点复杂的情况.我必须创建分析器/代码修复提供程序,例如仅分配参数但从未使用过,或者从不使用本地变量.
对于参数情况,我要进行方法声明并查看参数列表以获取所有分析器.我正在遍历方法中的赋值表达式,并且我过滤了使用辅助方法分配的参数.
它变得模糊的地方我不知道何时使用局部变量/参数.我已经完成了符号,但他们无法告诉我使用/未使用的变量.我可以尝试通过在字符串中转换方法声明语法上下文来查找方法中提到变量名称的次数,并查找已分配的参数,但这只是一个很糟糕的想法.
我真的被困住了,我会从那些曾经遇到过这种情况的人那里得到一些帮助.
对于可能会问的人,我主要是在寻找分析仪缺失的逻辑.我不知道代码修复提供程序将如何工作.如果您对我能做的事情有所了解,请随意将其包含在您的答案中!截至目前,我认为可以从方法中删除未使用的局部变量,同样可以使用未使用的参数.我现在不确定.
UPDATE
我现在正在尝试使用DataFlow API,但目前它并不适合我.这个帖子最古老的答案给了我一个起点,但实际上并没有起作用.
我想出了自己的方式:
private static bool IsLocalVariableBeingUsed(VariableDeclaratorSyntax variableDeclarator, SyntaxNodeAnalysisContext syntaxNode)
{
var model = syntaxNode.SemanticModel.Compilation.GetSemanticModel(variableDeclarator.SyntaxTree);
var methodBody = variableDeclarator.AncestorsAndSelf(false).OfType<MethodDeclarationSyntax>().First();
var lastMethodNode = methodBody?.ChildNodes().LastOrDefault();
if (lastMethodNode == null)
return false;
var readWrite = syntaxNode.SemanticModel.AnalyzeDataFlow(variableDeclarator, lastMethodNode);
}
Run Code Online (Sandbox Code Playgroud)
但这也行不通.使用NUnit测试时:
var input = @"
class TestClass {
void TestMethod ()
{
int i;
}
}";
Run Code Online (Sandbox Code Playgroud)
当运行时到达readWrite或result(从最旧的答案)时,我收到以下消息:
System.ArgumentOutRangeException Index was out of range Must be non negative and lesser than the size of the collection"
Run Code Online (Sandbox Code Playgroud)
但在此之前,在我的分析器中,当我尝试验证我的节点以确保它不是null并为数据流API创建适当的元素时,没有代码中断(不确定这是否是合适的术语)但是此刻我无法进步.
使用Visual Studio 2015 RTM,我有一个.NET 4.0类库项目.
我已经将Microsoft.CodeAnalysis.FxCopAnalyzersNuGet包添加到项目中.这导致在解决方案资源管理器中为项目列出以下分析器.
但是,在" 错误列表"窗口中,将显示以下错误:
无法加载分析器程序集C:\ Dev\git\MySolution\packages\System.Runtime.Analyzers.1.0.0\analyzers\dotnet\cs\System.Runtime.Analyzers.dll:无法加载文件或程序集'System.Runtime .Analyzers,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'或其中一个依赖项.强名称验证失败.(HRESULT异常:0x8013141A)
(和System.Runtime.CSharp.Analyzers和System.Runtime.InteropServices.Analyzers类似)
前两个分析仪确实可以正常工作,但我在最后四个分析中没有得到任何东西(可能与上述错误有关).
有没有办法让这些工作,或者它可能与项目是.NET 4.0有关?
请考虑以下表达式:
public override string ToString() => "ABCDEFG";
Run Code Online (Sandbox Code Playgroud)
汇编到这个:
public override string ToString()
{
return "ABCDEFG";
}
Run Code Online (Sandbox Code Playgroud)
尽管这种语法是语法糖,但我希望ToString()等同于Func<string>
Func<string> ToString = () => { return "ABCDEFG"; };
Run Code Online (Sandbox Code Playgroud)
请注意,Func<string>需要一个return语句,但ToString()覆盖的lambda语法不需要.
为什么覆盖的Lambda语法不需要使用return?
我想从C#中找出使用Roslyn的代码行.这是我试过的.
SyntaxTree tree = SyntaxTree.ParseText(@"int fun(int x){ int y = 0; x++; return x+1; return z;}
double funny(double x){ return x/2.13;}");
List<MethodDeclarationSyntax> methods = tree.GetRoot()
.DescendantNodes()
.Where(d => d.Kind == SyntaxKind.MethodDeclaration)
.Cast<MethodDeclarationSyntax>()
.ToList();
int lvc = methods[0].Body.Statements
.Count(x => x.Kind == SyntaxKind.LocalDeclarationStatement);
methods.Select(z => new { MethodName = z.Identifier.ValueText, LoC = z.Body.Statements.Count })
.OrderByDescending(x => x.LoC)
.ToList()
.ForEach(x => Console.WriteLine(x.MethodName + " " + x.LoC));
Run Code Online (Sandbox Code Playgroud)
我得到了以下输出
好玩的4
好笑1
但是我在函数中有两个return语句fun.该代码无法在实际设置中编译.使用Roslyn时如何使这些错误消失?
为什么是这样:
public int X { get; } = 5
public int Y { get; } = X;
Run Code Online (Sandbox Code Playgroud)
不可能?
因为手动执行:
public TestClass()
{
X = 5;
Y = X;
}
Run Code Online (Sandbox Code Playgroud)
工作,(显然?)这样做:
public static int X { get; } = 5;
public static int Y { get; } = X;
Run Code Online (Sandbox Code Playgroud)
有没有办法让第一个例子进行编译,还是我必须在ctor中手动完成?
(我真正的问题要复杂得多,不仅仅是整数,而是用于创建其他实例的实例,但这个例子更容易讨论)
我有这个步行者
internal class MyWalker : CSharpSyntaxWalker
{
public int MethodCount { get; private set; }
public MyWalker() : base(Microsoft.CodeAnalysis.SyntaxWalkerDepth.Trivia)
{ }
public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
{
MyMethodCount ++;
}
public override void VisitClassDeclaration(ClassDeclarationSyntax node)
{
Class++;
Complexity++;
}
}
Run Code Online (Sandbox Code Playgroud)
我用这段代码给walker打电话
var code = @"
public class foo
{
public void MyMethod()
{
}
}
";
SyntaxTree node = CSharpSyntaxTree.ParseText(source);
var root = node.GetRoot();
var walker = new MyWalker();
walker.Visit(root);
Run Code Online (Sandbox Code Playgroud)
但从未调用过访问MethodDeclaration.
为了确保我与SyntaxTree Analyzer进行比较,我可以看到roslyn应该将其识别为Method声明.

我错过了什么?
关于使用Roslyn添加C#语法糖的两部分问题:
首先,是否可以使用Roslyn向C#添加新语法,或者它总是必须是从有效C#到其他有效C#的转换?例如,我想做一些像VB.NET的XML文字:
XElement lvalue = <some><xml /></some>;
Run Code Online (Sandbox Code Playgroud)
是否可以在编译时将其转换为:
XElement lvalue = new XElement("some", new XElement("xml")); // or whatever
Run Code Online (Sandbox Code Playgroud)
其次,如果可能的话,对用户来说是什么样的?我可以这样做,以便编写第一个表达式,并且永远不会看到转换到第二个表达式(它在编译时透明地发生)?或者,Roslyn语法转换必须作为一种IDE"重构建议"出现?我对Roslyn的文档不清楚.
我正在研究IQueryable的实现; 但是,在我深入研究之前,我想确保我完全理解我需要评估的表达式树是什么样的.特别是,我很好奇在编译过程中如何将LINQ查询语法转换为方法语法.
我正在使用LINQPad来查看编译器生成的方法.我注意到在嵌套迭代中生成一个临时变量名来存储上层迭代的状态.这是一个例子:
from Event in EventQueue
from Ack in Event.Acknowledgements
where Ack.User == User.Name
select Event
Run Code Online (Sandbox Code Playgroud)
这相当于:
EventQueue
.SelectMany(
Event => Event.Acknowledgements,
(Event, Ack) =>
new
{
Event = Event,
Ack = Ack
}
)
.Where(temp0 => (temp0.Ack.User == User.Name))
.Select(temp0 => temp0.Event)
Run Code Online (Sandbox Code Playgroud)
当然,我的第一直觉是试图打破这一点,看看发生了什么.所以我写了以下查询:
from Event in EventQueue
from Ack in Event.Acknowledgements
let temp0 = Ack.User
where Ack.User == temp0
select Event
Run Code Online (Sandbox Code Playgroud)
这几乎是"WHERE 1 = 1"并返回所有事件; 但是,我不明白它是如何工作的,因为我给出的方法链永远不会编译:
EventQueue
.SelectMany(
Event => Event.Acknowledgements,
(Event, Ack) =>
new
{
Event = …Run Code Online (Sandbox Code Playgroud) 谁能告诉我为什么这两种匿名类型不一样?
{Name = "<>f__AnonymousType0`6" FullName = "<>f__AnonymousType0`6[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}
{Name = "<>f__AnonymousType0#1`6" FullName = "<>f__AnonymousType0#1`6[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}
Run Code Online (Sandbox Code Playgroud)
澄清:(我不知道它是否重要,但是一个匿名类型带有#符号。哦,#01)
我有这两段代码。在同一个类(程序集)中。一个返回上面的匿名类型之一,另一个返回另一个。但是,两者都在评估相同的表达式。
我做了下面的比较(有些只是为了查看结果,即使有些应该正确地返回false)。但是,它们都返回false。(我可能遗漏了一些我尝试过的东西)
ms返回匿名类型之一。resultOfSelect返回另一个匿名类型。
注意:第二段代码中的methodArgumentStringContainingSelectStatement包含与字符串相同的表达式。
'ms == resultOfSelect'
'ms.GetType()== resultOfSelect'
'ms.GetType()。Equals(resultOfSelect.GetType())'
'ms.GetType()== resultOfSelect.GetType()'
resultOfSelect debugView是:
{Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable <<> f__AnonymousType0#1>} …
roslyn ×10
c# ×9
c#-6.0 ×2
linq ×2
analyzer ×1
constructor ×1
ef-core-2.0 ×1
lambda ×1
linqpad ×1
properties ×1