相关疑难解决方法(0)

你在MSIL中可以做些什么,你不能用C#或VB.NET做什么?

用.NET语言编写的所有代码都编译为MSIL,但是只有使用MSIL才能直接执行特定的任务/操作吗?

让我们在MSIL中比C#,VB.NET,F#,j#或任何其他.NET语言更容易完成.

到目前为止我们有这个:

  1. 尾递归
  2. 通用Co/Contravariance
  3. 重载仅在返回类型上有所不同
  4. 覆盖访问修饰符
  5. 有一个不能从System.Object继承的类
  6. 过滤的异常(可以在vb.net中完成)
  7. 调用当前静态类类型的虚方法.
  8. 获取值类型的盒装版本的句柄.
  9. 做一个尝试/错误.
  10. 使用禁用名称.
  11. 为值类型定义自己的无参数构造函数.
  12. 使用raise元素定义事件.
  13. CLR允许一些转换,但C#不允许转换.
  14. 做一个非main()方法作为.entrypoint.
  15. 直接使用本机int和本机unsigned int类型.
  16. 玩瞬态指针
  17. MethodBodyItem中的emitbyte指令
  18. 抛出并捕获非System.Exception类型
  19. 继承枚举(未验证)
  20. 您可以将字节数组视为(4x更小)整数数组.
  21. 您可以使字段/方法/属性/事件具有相同的名称(未验证).
  22. 您可以从自己的catch块分支回try块.
  23. 您可以访问famandassem访问说明符(protected internal是fam assem)
  24. 直接访问<Module>类以定义全局函数或模块初始值设定项.

.net c# clr cil

161
推荐指数
13
解决办法
9231
查看次数

为什么我的C#数组在转换为对象时会丢失类型符号信息?

调查一个bug,我发现这是由于c#中的这种奇怪:

sbyte[] foo = new sbyte[10];
object bar = foo;
Console.WriteLine("{0} {1} {2} {3}",
        foo is sbyte[], foo is byte[], bar is sbyte[], bar is byte[]);
Run Code Online (Sandbox Code Playgroud)

输出为"True False True True",而我希望" bar is byte[]"返回False.显然酒吧既是一个byte[]又是一个sbyte[]?同样的情况对于其他符号/无符号类型,如Int32[]VS UInt32[],但不是说Int32[]VS Int64[].

谁能解释这种行为?这是在.NET 3.5中.

c# arrays types command-line-interface

42
推荐指数
3
解决办法
2361
查看次数

在C#中从uint []转换为int []后调用ToList()的异常

我得到了System.ArrayTypeMismatchException: Source array type cannot be assigned to destination array type此代码段的异常:

var uints = GetArray();
if (uints is int[])
{
    var list = ((int[])uints).ToList(); // fails when call ToList()
}

private Array GetArray()
{
    var result = new uint[] { uint.MaxValue, 2, 3, 4, 5 };
    return result;
}
Run Code Online (Sandbox Code Playgroud)

然后我求助于Jon的回答为什么在C#中"int []是uint [] == true",它告诉我,由于GetArray()返回a Array,转换在运行时被推迟,而CLR允许这种转换int[] to uint[](vice versa).如果我在转换后检查值,它实际上工作正常:

foreach (var i in ((int[])units))
{
    System.Console.WriteLine(i.GetType());
    System.Console.WriteLine(i);
}
Run Code Online (Sandbox Code Playgroud)

我会得到:

System.Int32
-1
System.Int32 …
Run Code Online (Sandbox Code Playgroud)

c#

9
推荐指数
2
解决办法
294
查看次数

如何使用IEnumerable.Cast <>和.ToArray()将int数组转换为枚举数组?

考虑以下枚举声明和int数组:

enum Test { None };

int[] data = {0};
Run Code Online (Sandbox Code Playgroud)

要将此int[]数组转换为Test[]数组,我们可以简单地执行此操作:

Test[] result = Array.ConvertAll(data, element => (Test)element);
Run Code Online (Sandbox Code Playgroud)

我最初试图这样做:

Test[] result = data.Cast<Test>().ToArray();
Run Code Online (Sandbox Code Playgroud)

但是,它会在运行时抛出异常:

System.ArrayTypeMismatchException:无法将源数组类型分配给目标数组类型.

问题一

有没有办法使用Linq并Cast<>没有错误,或者我必须使用Array.Convert()

问题二(在第一个问题得到正确回答后添加)

究竟为什么不起作用?

看起来这是一个实现细节逃逸的情况......考虑:

这会导致错误:

var result = data.Cast<Test>().ToList(); // Happens with "ToList()" too.
Run Code Online (Sandbox Code Playgroud)

但这不是:

var result = new List<Test>();

foreach (var item in data.Cast<Test>())
    result.Add(item);
Run Code Online (Sandbox Code Playgroud)

这也不是:

var result = data.Select(x => x).Cast<Test>().ToList();
Run Code Online (Sandbox Code Playgroud)

明确的含义是在.ToList()实现中正在进行某种优化,导致此异常.


附录:

这也有效:

List<int> data = new List<int>{0};
var result …
Run Code Online (Sandbox Code Playgroud)

.net c# linq ienumerable

8
推荐指数
1
解决办法
671
查看次数

可以`typeof(T).IsAssignableFrom(x.GetType())`安全地重写为`x is T`?

注意:这不是"使用IsAssignableFrom和"是"C#中的关键字"的副本.另一个问题是typeof(T).IsAssignableFrom(type)),哪里type不是一个object而是一个Type.

这似乎微不足道 - 我可以听到你说,"只要打电话x.GetType()!" - 但是由于下面提到的与COM相关的角落情况,该调用会导致问题,这就是我要求重写的原因.

......还是有罕见的特殊情况,两者可能会给出不同的结果?

我偶然发现了一张表格的类型检查:

typeof(TValue).IsAssignableFrom(value.GetType())
Run Code Online (Sandbox Code Playgroud)

where TValue是泛型类型参数(没有任何约束)并且valueobject.

我不完全确定将上述内容重写为以下是否安全:

value is TValue
Run Code Online (Sandbox Code Playgroud)

据我所知,这两个测试是相同的,但COM对象除外.is应该触发一个正确的QueryInterface,同时IsAssignableFrom可能会被__ComObjectRCW包装类型混淆并报告错误否定.

是否有任何其他差异is和显示的使用IsAssignableFrom

.net c# reflection types system.type

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

为什么根据我初始化值的方式,将IEnumerable <T>的值转换为不同的行为?

我有一些代码,它采用一个值(类型为object)并尝试将其转换为IEnumerable的int和uint,如下所示:

var idList = value as IEnumerable<int>;
var uintList = value as IEnumerable<uint>;
Run Code Online (Sandbox Code Playgroud)

以这种方式初始化值时:

uint number = 1;
object value = new []{ number };
Run Code Online (Sandbox Code Playgroud)

idList和uintList都有值,但调用idList.ToList()会产生一个ArrayTypeMismatchException.但是,当生成值时new List<uint>{ number },idList按预期为null.

此外,var idList = value as IEnumerable<int>;即使使用集合初始值设定项生成值,在VS 2015中调用即时窗口也会返回null,就像我预期的那样.

.Net小提琴在这里重现错误.

这里发生了什么?

c# casting

6
推荐指数
1
解决办法
189
查看次数

将int []转换为对象时,意外的运算符是/作为行为

有人可以解释为什么会这样吗?

var y = new int[]{1,2};

Console.WriteLine(y is uint[]); // false
Console.WriteLine(((object)y) is uint[]); // true
Run Code Online (Sandbox Code Playgroud)

c#

4
推荐指数
1
解决办法
91
查看次数

C#params明显的编译器错误(C#5.0)

这是我认为昨天解决的一个帖子的后续内容.昨天我在以下情况下遇到了我的代码问题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    class Program
    {
        class Bar
        {
            int v;

            public Bar(int v) { this.v = v; }
            public override string ToString() { return v.ToString(); }
        }

        static void Main(string[] args)
        {
            Foo(1, 2, 3);
            Foo(new int[] { 1, 2, 3 });
            Foo(new Bar(1), new Bar(2), new Bar(3));
            Foo(new Bar[] { new Bar(1), new Bar(2), new Bar(3) });
            System.Threading.Thread.Sleep(20000);
        }

        static void Foo(params object[] objs)
        {
            Console.WriteLine("New call …
Run Code Online (Sandbox Code Playgroud)

c# params c#-5.0

0
推荐指数
2
解决办法
786
查看次数