小编con*_*low的帖子

这是一个C#4.0编译器可选参数bug吗?

我正在编写自定义安全属性并得到奇怪的编译器行为...当我在同一文件中使用该属性时,默认参数值工作正常:

using System.Security.Permissions;

[System.Serializable]
sealed class FooAttribute : CodeAccessSecurityAttribute {
    public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { }
    public override System.Security.IPermission CreatePermission() { return null; }
}

[Foo] class Program {
    static void Main(string[] args) { }
}
Run Code Online (Sandbox Code Playgroud)

但是当我将上面的代码分成两个文件时 - 文件1:

using System.Security.Permissions;

[System.Serializable]
sealed class FooAttribute : CodeAccessSecurityAttribute {
    public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { }
    public override System.Security.IPermission CreatePermission() { return null; }
}
Run Code Online (Sandbox Code Playgroud)

和文件2:

[Foo] class Program {
    static void Main(string[] args) { } …
Run Code Online (Sandbox Code Playgroud)

c# attributes optional-parameters c#-4.0

13
推荐指数
1
解决办法
478
查看次数

这是一个ExpressionTrees错误吗?

using System;
using System.Linq.Expressions;

class Program
{
  static void Main()
  {
    Expression<Func<float, uint>> expr = x => (uint) x;

    Func<float,uint> converter1 = expr.Compile();
    Func<float,uint> converter2 = x => (uint) x;

    var aa = converter1(float.MaxValue); // == 2147483648
    var bb = converter2(float.MaxValue); // == 0
  }
}
Run Code Online (Sandbox Code Playgroud)

编译Expression.Convert此转换时可以建立相同的不同行为:

Single -> UInt32 Single -> UInt64

Double -> UInt32 Double -> UInt64

看起来很奇怪,不是吗?

<===添加了一些我的研究===>

我看了DynamicMethod使用DynamicMethod Visualizer编译的MSIL代码和一些反射hack来DynamicMethod从编译中获取Expression<TDelegate>:

Expression<Func<float, uint>> expr = x => (uint) …
Run Code Online (Sandbox Code Playgroud)

.net c# expression-trees

11
推荐指数
1
解决办法
363
查看次数

这是一个ExpressionTrees错误吗?#3

在搜索用户定义的运算符时,表达式类应该更准确吗?

sealed class Foo
{
  // just the private static method!
  private static int op_Implicit() { return 1; }

  public static implicit operator int(Foo foo) { return 2; }
}

public class Program
{
  private static void Main()
  {
    var param = Expression.Parameter(typeof(Foo), "x");

    // IndexOutOfRangeException was unhandled!
    var lambda = Expression.Lambda<Func<Foo, int>>(
      Expression.Convert(param, typeof (int)), param);
  }
}
Run Code Online (Sandbox Code Playgroud)

此外,可以使用多个参数定义static op_Explicitop_Implicitmethod,Expression类将此方法作为用户定义的运算符接受!

ps ExpressionTrees正在寻找带有BindingFlags.NonPublicflag的运算符,它允许搜索用户类型中的运算符,而不是System.Core.dll直接可见,但它也允许Expressions API查找"看起来像"用户定义的运算符的私有方法.但是C#规则不允许您定义和使用非公共运算符!我认为Expressions API的行为应该是相同的......

.net c# expression-trees

11
推荐指数
0
解决办法
774
查看次数

C#类型参数规范

从一些特殊类型的CLI mscorlib程序库(ArgIterator,TypedReferenceRuntimeArgumentHandle类型)不能被用作一般类型参数构造通用类型/方法:

void Foo<T>() { }
void Bar() { Foo<ArgIterator>(); }
Run Code Online (Sandbox Code Playgroud)

提供编译器错误:

error CS0306: The type 'System.ArgIterator' may not be used as a type argument
Run Code Online (Sandbox Code Playgroud)

但是在C#规范中根本没有记录.

这些类型是CLI规范的一部分还是CLR实现提供的这种类型,上述行为不应该在C#规范中记录?

c# generics specifications type-parameter

11
推荐指数
2
解决办法
1997
查看次数

C#4.0'动态'和foreach声明

在我发现之前的很长一段时间,新的dynamic关键字与C#的foreach声明不兼容:

using System;

sealed class Foo {
    public struct FooEnumerator {
        int value;
        public bool MoveNext() { return true; }
        public int Current { get { return value++; } }
    }

    public FooEnumerator GetEnumerator() {
        return new FooEnumerator();
    }

    static void Main() {
        foreach (int x in new Foo()) {
            Console.WriteLine(x);
            if (x >= 100) break;
        }

        foreach (int x in (dynamic)new Foo()) { // :)
            Console.WriteLine(x);
            if (x >= 100) break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我期望迭代 …

ienumerable foreach dynamic c#-4.0

11
推荐指数
1
解决办法
8497
查看次数

为什么.NET异常是可变的?

我想知道为什么基类库中的.NET异常类默认有一些可变成员

  • 为什么我可以改变Source,HelpLink和值Data,但不能改变其他任何像Message
  • 为什么抛出异常会重写StackTrace使它变得可变?将堆栈跟踪信息附加到现有跟踪是更好的设计(但仍然可变)?
  • .NET异常设计可能有哪些改进?

我只是在设计选择上很有意思......

.net exception-handling exception throw

11
推荐指数
1
解决办法
260
查看次数

在C#中,`x is int?`和`x is int`之间有区别吗?

class C<T> where T : struct {
    bool M1(object o) => o is T;
    bool M2(object o) => o is T?;
}
Run Code Online (Sandbox Code Playgroud)

传递null引用或盒装T值时,上述两种方法似乎表现相同.但是,生成的MSIL代码有点不同:

.method private hidebysig instance bool M1(object o) cil managed {
    .maxstack 8
    IL_0000: ldarg.1
    IL_0001: isinst !T
    IL_0006: ldnull
    IL_0007: cgt.un
    IL_0009: ret
}
Run Code Online (Sandbox Code Playgroud)

VS

.method private hidebysig instance bool M2(object o) cil managed {
    .maxstack 8
    IL_0000: ldarg.1
    IL_0001: isinst valuetype [mscorlib]System.Nullable`1<!T>
    IL_0006: ldnull
    IL_0007: cgt.un
    IL_0009: ret
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,o is …

c# boxing types cil nullable

11
推荐指数
1
解决办法
223
查看次数

这是一个ExpressionTrees错误吗?#2

看起来ExpressionTrees编译器应该在许多行为中接近C#规范,但与C#不同,不支持从decimal任何行为转换enum-type:

using System;
using System.Linq.Expressions;

class Program
{
  static void Main()
  {
    Func<decimal, ConsoleColor> converter1 = x => (ConsoleColor) x;
    ConsoleColor c1 = converter1(7m); // fine

    Expression<Func<decimal, ConsoleColor>> expr = x => (ConsoleColor) x;

    // System.InvalidOperationException was unhandled
    // No coercion operator is defined between types
    // 'System.Decimal' and 'System.ConsoleColor'.

    Func<decimal, ConsoleColor> converter2 = expr.Compile();

    ConsoleColor c2 = converter2(7m);
  }
}
Run Code Online (Sandbox Code Playgroud)

其他很少使用的C#显式转换,如double -> enum-type存在,并按照C#规范中的说明工作,但不是decimal -> enum-type.这是一个错误吗?

.net c# expression-trees

10
推荐指数
1
解决办法
884
查看次数

F#:运算符绑定中的显式类型参数

我正在尝试使用显式类型参数和约束来定义运算符:

let inline (===)<'a, 'b
    when 'a : not struct
     and 'b : not struct> a b = obj.ReferenceEquals (a,b)
Run Code Online (Sandbox Code Playgroud)

它在F#2.0中运行良好,但产生:

警告FS1189:
类型参数必须直接放在类型名称旁边,例如"type C <'T>",而不是类型"C <'T>"

那么为运算符定义做出显式类型参数规范的正确方法是什么?

ps请不要告诉我隐式类型参数和其他一些解决方法,我想具体解决这个问题.

generics f# explicit operators type-parameter

10
推荐指数
1
解决办法
374
查看次数

System.Dynamic错误?

当我玩C#4.0动态时,我发现像这样的代码发生了奇怪的事情:

using System.Dynamic;

sealed class Foo : DynamicObject
{
    public override bool TryInvoke(
        InvokeBinder binder, object[] args, out object result)
    {
        result = new object();
        return true;
    }

    static void Main()
    {
        dynamic foo = new Foo();

        var t1 = foo(0);
        var t2 = foo(0);
        var t3 = foo(0);
        var t4 = foo(0);
        var t5 = foo(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

好的,它可以工作但是......看看IntelliTrace窗口:

截图http://img717.imageshack.us/img717/4914/10435230.png

因此,每次调用(以及动态对象上的其他操作)都会导致抛出和捕获奇怪的异常两次!

我理解,有时可以使用异常机制进行优化,例如,可以对某个存根委托执行对动态的第一次调用,这只会抛出异常 - 这可能就像是动态绑定器的信号来解析正确的成员并重新指向代表.下一次对同一代表的调用将在没有任何检查的情况下执行.

但是......上面代码的行为看起来很奇怪.也许每次对DynamicObject进行两次抛出和捕获异常 - 是一个错误?

.net c# dynamic c#-4.0

9
推荐指数
1
解决办法
942
查看次数