标签: roslyn

我可以使用Roslyn进行编译时代码重写吗?

比如我有

class Foo: INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    public int Bar {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我可以在编译时获取Foo类AST并重写Bar

    public string Bar
    {
        get { return this.bar; }

        set 
        {
            if (value != this.bar)
            {
                this.phoneNumberValue = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Bar"));
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

.

c# metaprogramming compiler-as-a-service roslyn

16
推荐指数
1
解决办法
4042
查看次数

如何用Roslyn声明var变量?

我有以下代码,但我找不到如何获取var TypeSyntax.有任何想法吗?

Syntax.LocalDeclarationStatement(                   
    declaration: Syntax.VariableDeclaration(
        type: Syntax.PredefinedType(Syntax.Token(SyntaxKind.VarKeyword)),
        variables: Syntax.SeparatedList(
        Syntax.VariableDeclarator(
            identifier: Syntax.Identifier(name)))
        )
    )
);
Run Code Online (Sandbox Code Playgroud)

这失败了一个Argument异常,上面写着:"keyword"

c# roslyn

16
推荐指数
3
解决办法
3062
查看次数

空传播算子和动态变量

我一直在研究C#6中的零传播运算符,并尝试使用dynamic类型的变量,但没有成功.考虑下面的代码,它会编译,但是AccessViolationException当将null传播应用于动态对象时,CLR会在运行时抛出.

class SomeType
{
    public object SomeProperty { get; set; }

    static void Main()
    {
        var obj = new SomeType() { SomeProperty = "ABCD" };

        var p1 = ((dynamic)obj).SomeProperty;   //OK, p1 is set to "ABCD"
        var p2 = ((dynamic)obj)?.SomeProperty;  //AccessViolationException

        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

起初我认为这可能是一个错误,但后来我想到了structs.通常,您不能将?.运算符应用于值类型变量(因为它不能为null).但是您可以将其转换为dynamic然后应用运算符.所以我改成SomeTypestruct并得到了同样的例外.

问题是,根据设计,动态变量的零传播总是会抛出异常,因为底层对象可能是值类型?

AccessViolationException无论如何,这是非常丑陋的,当你运行代码时,你得到相同的一个吗?

c# dynamic roslyn c#-6.0

16
推荐指数
1
解决办法
755
查看次数

C#6/C++ ref关键字错误

我用我现有的解决方案尝试了VS2015,我得到了一些有效的新错误(比如编译器之前没有捕获到的无法访问的代码),但是我在这一行上也遇到了错误:

bool bWasAlreadyLocked = false;
oEnv.LockDoc(oWarnings, oEventDoc, ref bWasAlreadyLocked);
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

错误CS1503参数3:无法从'ref bool [mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]'转换为'ref bool [mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089] "

我不明白为什么它会抛出那个错误,显然类型确实匹配.这是新编译器中的错误还是ref关键字的行为发生了变化?

这种情况下的函数是一个C++函数,它使用从c ++类派生的ac#类导入到C#.它的签名是这样的:

void CBkgDocEnvX::LockDoc(
CFIWarningList ^oWarnings,
CBaseDoc ^oBaseDoc,
// Output
bool %rbWasAlreadyLocked)
Run Code Online (Sandbox Code Playgroud)

值得一提的是,我现在选择在解决方案中使用VS2013 c ++编译器作为c ++源代码,因此c ++方面应该与以前一样.我的猜测是c#和c ++之间的互操作发生了变化.

c# c++ interop ref roslyn

16
推荐指数
1
解决办法
1000
查看次数

TFS不会编译字符串插值语法

我在上周发布时更新到Visual Studio 2015.Resharper建议我可以使用以下命令更新以下字符串string.Format:

string filePath = HttpContext.Server.MapPath(string.Format("~/App_Data/{0}.xlsx", Guid.NewGuid()));
Run Code Online (Sandbox Code Playgroud)

要使用字符串插值:

string filePath = HttpContext.Server.MapPath($"~/App_Data/{Guid.NewGuid()}.xlsx");
Run Code Online (Sandbox Code Playgroud)

我这样做了,一切都很好.

但是我打破了TFS的构建:

Controllers\MyController.cs(224):意外字符'$'

因此,我们较旧的非更新版本的TFS似乎无法编译C#6中的新功能.

该项目仍然以使用框架4.5为目标,但我没有针对4.6.我(错误地)认为仍然以旧框架为目标意味着它可以由仍然使用VS2013和我们的TFS构建服务器的其他团队成员构建.

所以看起来我们的TFS需要更新......某些东西.

我需要在TFS服务器上安装什么才能让它编译这个新语法?最新版本的.NET Framework还是其他什么?

tfs roslyn visual-studio-2015

16
推荐指数
2
解决办法
1万
查看次数

C#6 null条件运算符不适用于LINQ查询

我希望这可以工作,但显然IL生成的方式,它抛出NullReferenceException.为什么编译器不能为查询生成类似的代码?

在这种ThisWorks情况下,编译器生成的代码短路表达式的其余部分,为什么它不能为LINQ查询案例做同样的事情?

class Target
{
    public ChildTarget Child;
}

class ChildTarget
{
    public int[] Values;
}

IEnumerable<int> ThisWorks(Target target) =>
    target.Child?.Values.Select(x => x);

IEnumerable<int> ThisDoesNotWork(Target target) =>
    from x in target.Child?.Values select x;

ThisWorks(new Target());
ThisDoesNotWork(new Target()); // this throws NullReferenceException
Run Code Online (Sandbox Code Playgroud)

反编译结果

private static IEnumerable<int> ThisDoesNotWork(Target target)
{
    ChildTarget child = target.Child;
    IEnumerable<int> values = (child != null) ? child.Values : null;
    Func<int, int> func;
    if ((func = Program._func) == null)
    {
        func = (Program._func = …
Run Code Online (Sandbox Code Playgroud)

c# linq roslyn

16
推荐指数
1
解决办法
1268
查看次数

编译时使用的Bug?导致PEVerify失败的错误图像

我偶然发现了一些奇怪的事情:我BadImageFormatException不知道它可能会引用什么图像(汇编).

我减少了解决方案,使它只包含一个没有依赖项的项目:

在此输入图像描述

如您所见,它只使用System(和mscorlib),当然我不会在运行时加载程序集.

它编译为AnyCpu与.NET 4.5.2,VS 2015与C#6,虽然这些都不重要.

我尝试使用C#5制作样本,但是一旦我替换了所有的"?".运营商,它停止发生.

我主持了这个项目,以便人们可以自己尝试:

git clone -b crash-sample https://github.com/jtheisen/moldinium.git
Run Code Online (Sandbox Code Playgroud)

我在4台机器上进行了清洁和测试,所有这些都显示出相同的效果.

崩溃的堆栈跟踪是:

Ex.: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
   at IronStone.Moldinium.LiveList.<>c__DisplayClass10_0`1.<Where>b__2(ListEvent`1 v)
   at IronStone.Moldinium.ActionObserver`1.OnNext(T value) in C:\Source\Repos\moldinium\ConsoleApplication1\Rx.cs:line 51
...snipped...
Run Code Online (Sandbox Code Playgroud)

在输出上运行PEVerify会产生以下错误:

[IL]:错误:[C:\ Source\Repos\moldinium\ConsoleApplication1\bin\Debug\Bad.exe:IronStone.Moldinium.LiveList + <> c__DisplayClass10_0`1 [TSource] :: b__2] [offset 0x0000013B]无法解析令牌.

?.从Select.cs文件中删除所有操作符可以解决该问题.

使用ILSpy我已将问题隔离到:

IronStone.Moldinium.LiveList.<>c__DisplayClass10_0`1.<Where>b__2
Run Code Online (Sandbox Code Playgroud)

您可以在主旨看(通过ILSpy)方法的IL转储这里.Bad IL是使用?.Good IL时的C#5.0风格.

这是用VS2015.3构建的

CSC版本:Microsoft(R)Visual C#编译器版本1.3.1.60616

c# roslyn c#-6.0 visual-studio-2015

16
推荐指数
1
解决办法
295
查看次数

Roslyn如何与MsBuild相关?

我想知道:Roslyn究竟与MsBuild有什么关系?

我的理解是这样的

  1. Roslyn是一个编译引擎
  2. MsBuild主要是一组如何设置项目的规范 - 即基本上是.csproj,.sln文件等的定义模式.

然后,MsBuild还附带了一个msbuild.exe - 如果我错了,请纠正我,能够实际编译项目.但是,假设msbuild.exe可以编译项目,那么如何与Roslyn相提并论呢,但Roslyn也是如此?

在MSBuild 15的情况下,msbuild.exe是否使用Roslyn进行编译?它们是完全分开的吗?我误会了什么吗?

而且更具体地说:假设我想以编程方式创建简单的.csproj文件,并使用Roslyn的MSBuildWorkspace来处理/填充并最终编译这些文件.我的应用程序的最终用户是否需要在其计算机上安装Microsoft的构建工具?或者这不是必需的,因为Roslyn能够独立于任何本地MSBuild安装来读取和编译这些内容吗?

c# msbuild roslyn

16
推荐指数
1
解决办法
3778
查看次数

禁用"名称可以简化"IDE0003修复提示

this即使在选项中禁用了检查,Visual Studio 2017 也会显示不必要限定符的提示.

这是它的样子:

(第一行是罪魁祸首,第二行是我多么希望this永远的样子.)

将鼠标悬停在灰色this并点击灯泡上会显示以下建议修复: 在此输入图像描述

我找不到完全禁用它的方法.有时我想要"不必要的" this限定符,有时候我没有,所以我不希望VS对此发表评论.

"无"是最不严格的选择,但它仍然显示出这种烦人的,不同的颜色.
在此输入图像描述


是否有可能完全禁用此检查?

.net c# roslyn visual-studio-2017

16
推荐指数
1
解决办法
3708
查看次数

项目文件中的“EnforceExtendedAnalyzerRules”标志有什么作用

在使用 Roslyn 分析器工作期间,我收到了来自 Roslyn 分析器的警报,该警报检查 Roslyn API 的正确使用情况。

RS1036:指定分析器禁止 API 强制设置。

包含分析器或源生成器的项目应指定属性“<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>”。

我尝试用谷歌搜索该属性的用途,但没有找到任何其他信息。这是我已经检查过的链接:

https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.md#rs1036-specify-analyzer-banned-api-enforcement-setting

你知道这面旗帜有什么作用吗?

csproj roslyn roslyn-code-analysis

16
推荐指数
1
解决办法
5071
查看次数