相关疑难解决方法(0)

为什么有些C#lambda表达式编译为静态方法?

正如您在下面的代码中看到的,我已将Action<>对象声明为变量.

有人请让我知道为什么这个动作方法委托表现得像一个静态方法?

为什么它会true在以下代码中返回?

码:

public static void Main(string[] args)
{
    Action<string> actionMethod = s => { Console.WriteLine("My Name is " + s); };

    Console.WriteLine(actionMethod.Method.IsStatic);

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

输出:

示例输出示例

.net c# reflection lambda

121
推荐指数
3
解决办法
8143
查看次数

为什么没有捕获的lambda从C#5中的静态变为C#6中的实例方法?

此代码在标记的行上引发异常:

using System;
using System.Linq.Expressions;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Action<int, int> a = (x, y) => Console.WriteLine(x + y);

            ParameterExpression p1 = Expression.Parameter(typeof(int), "p1");
            ParameterExpression p2 = Expression.Parameter(typeof(int), "p2");

            // Here is the exception ArgumentNullException.
            MethodCallExpression call = Expression.Call(a.Method, p1, p2);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我已经在VS2013(就像魅力)和VS2015社区(抛出异常)中测试了这段代码.

我跟着.Net参考源,这导致我有一些代码条件,检查是否提供了方法IsStatic.

在我的例子中,我传递的方法(a.Method)在VS2013中是静态的,并且由于某种原因在VS2015中是非静态的(实例).如果没有,它会抛出,告诉我我没有提供Instance论据.

为什么会这样?如何避免这种情况,以便Expression.Call在新的Visual Studio中重新开始工作?

c# visual-studio-2013 c#-6.0 visual-studio-2015

31
推荐指数
2
解决办法
1871
查看次数

Assembly.GetTypes()的行为在Visual Studio 2015中已更改

我昨天在Visual Studio 2015中打开了我们的解决方案,我们的一些单元测试(在Visual Studio 2013中运行正常)开始失败.Digger更深入我发现这是因为召集GetTypes()一个程序集返回了不同的结果.我已经能够创建一个非常简单的测试用例来说明它.

在Visual Studio 2013和2015中,我使用.NET Framework 4.5.2创建了一个新的控制台应用程序.我在以下两个项目中都添加了以下代码.

class Program
{
    static void Main(string[] args)
    {
        var types = typeof(Program).Assembly.GetTypes()
                .Where(t => !t.IsAbstract && t.IsClass);

        foreach (var type in types)
        {
            Console.WriteLine(type.FullName);
        }

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

当我在Visual Studio 2013中运行时,我得到以下输出(如预期的那样).

VS2013Example.Program

当我在Visual Studio 2015中运行时,我得到以下输出(不是预期的).

VS2015Example.Program

VS2015Example.Program + <>Ç

那是什么VS2015Example.Program+<>c类型的?原来它是.Where()方法中的lambda .是的,这是正确的,不知何故,本地lambda作为一种类型暴露.如果我.Where()在VS2015中注释掉,那么我就不再获得第二行了.

我已经使用Beyond Compare来比较两个.csproj文件,但唯一的区别是VS版本号,项目GUID,默认命名空间和程序集的名称,VS2015有一个对System.Net.Http的引用, VS2013一个没有.

有没有人见过这个?

有没有人解释为什么局部变量将在程序集级别作为类型公开?

c# compiler-construction roslyn visual-studio-2013 visual-studio-2015

25
推荐指数
1
解决办法
816
查看次数

为什么编译器在没有闭包时为委托添加额外的参数?

我正在玩,delegates并注意到当我创建一个Func<int,int,int>类似下面的例子时:

Func<int, int, int> func1 = (x, y) => x * y;
Run Code Online (Sandbox Code Playgroud)

编译器生成的方法的签名不是我所期望的:

在此输入图像描述

正如您所看到的,它需要一个对象作为它的第一个参数.但是当有一个关闭时:

int z = 10;
Func<int, int, int> func1 = (x, y) => x * y * z;
Run Code Online (Sandbox Code Playgroud)

一切都按预期工作:

在此输入图像描述

这是带有额外参数的方法的IL代码:

    .method private hidebysig static int32  '<Main>b__0'(object A_0,
                                                     int32 x,
                                                     int32 y) cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       8 (0x8)
  .maxstack  2
  .locals init ([0] int32 V_0)
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  mul …
Run Code Online (Sandbox Code Playgroud)

c# delegates cil

24
推荐指数
1
解决办法
442
查看次数

2013和2015调试编译之间的匿名方法静态不同

我希望有人可以识别出导致下面程序行为发生变化的语言特性(或bug).如果提供给Orchard :: Go的委托不是静态的,则会从更大的场景中重现它,该场景旨在记录消息.

using System;

namespace Sample
{
    public static class Program
    {
        public static void Main()
        {
            new Apple();
        }
    }

    public sealed class Apple
    {
        public Apple()
        {
            Orchard.Go(() => { });
        }
    }

    internal static class Orchard
    {
        public static void Go(Action action)
        {
            Console.WriteLine(action.Method.IsStatic);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

场景是:

  • 如果我编译并运行使用Visual Studio 2013生成的调试版本,则输出为True.
  • 如果我编译并运行使用Visual Studio 2015生成的调试版本,则输出为False.
  • 在这两种情况下,目标.NET Framework都是4.5.
  • 如果我编译并运行使用Visual Studio 2015生成的发布版本,则输出为True(因此与Visual Studio 2013一致).
  • Visual Studio 2015是RC版本(如果重要的话). …

c#

7
推荐指数
1
解决办法
239
查看次数

Lambda在Visual Studio 2015中被视为已关闭的委托

我很惊讶这两个委托(fn1fn2)之间会有任何运行时差异:

static int SomeStaticMethod(int x) { return x; }

// fn1.Target == null in this case
Func<int, int> fn1 = SomeStaticMethod;

// fn2.Target != null in this case
Func<int, int> fn2 = x => x;
Run Code Online (Sandbox Code Playgroud)

但显然第二个lambda被视为实例方法,因为它的Target属性是非null.在我切换到Visual Studio 2015之前,它的处理方式不同(在VS2012中,我很确定它被视为静态方法).

是否有理由将没有闭包的lambda视为C#中的闭合委托(即实例方法)?我想也许这是调试器添加一些东西,但它也发生在发布版本中.

(澄清)

关键是,我有一个这样的方法,它创建了一个通用委托,用于快速从枚举转换为int(无需装箱):

private static Func<int, TEnum> CreateIntToEnumDelegate()
{
    Func<int, int> lambda = x => x;
    return Delegate.CreateDelegate(typeof(Func<int, TEnum>), lambda.Method) 
        as Func<int, TEnum>;
}
Run Code Online (Sandbox Code Playgroud)

它不再适用于Roslyn,因为"实例"lambda与委托签名不兼容.所以我不得不使用一种static方法,没什么大不了的.

但令我担心的是,这在编译期间无法捕获.这个帖子描述了类似的问题,顺便说一句,现在我搜索了"Roslyn代表".

c# lambda closures visual-studio-2015

5
推荐指数
1
解决办法
283
查看次数

对于某些lambda表达式,为什么Action.Method.IsStatic在Visual Studio 2013和2015之间有所不同

鉴于以下控制台程序:

class Program
{
    private static string _value;
    static void Main(string[] args)
    {
        var t = new Action(() => _value = "foo");
        Console.Out.WriteLine("t.Method.IsStatic: {0}", t.Method.IsStatic);
    } 
}
Run Code Online (Sandbox Code Playgroud)

当使用VS 2013针对.Net 4.5.2编译时,它将打印出来

t.Method.IsStatic: true
Run Code Online (Sandbox Code Playgroud)

当使用VS 2015针对.Net 4.5.2编译时,它将打印出来

t.Method.IsStatic: false
Run Code Online (Sandbox Code Playgroud)

这个问题,我有点理解发生了什么,但我很困惑为什么VS的版本之间的行为发生了变化.根据我的理解,2013年的输出是正确的.

c# roslyn visual-studio-2013 visual-studio-2015

5
推荐指数
1
解决办法
102
查看次数