两个不同的枚举类型,例如:
public enum MyEnumA { A, B, C, }
public enum MyEnumB { X, Y, Z, }
在反射时
bool b = typeof(MyEnumB[]).IsAssignableFrom(typeof(MyEnumA[]));
b的值居然是true...
而无论csharp编译器,还是clr,都认为MyEnumA[]是无法转换成MyEnumB[]还有,上次那个非0为底的一维数组无法变成强类型估计也是ms的bug
真不知道ms的单元测试是怎么做的,这么低级的bug也会出现在Framework的release版本里面
让我白白浪费两天时间检查我Emit的IL是不是有什么bug,郁闷

解决方案 »

  1.   

    呵呵 楼主这几天发现的Bug真不少 
    作为开发工具
    vs算是比较智能的
      

  2.   

    jf
    bug 多多  ,发现一个,记住一个 。
      

  3.   

    IsAssignableFrom方法似乎认为任何枚举都是可以互相转换的
      

  4.   

    楼主很强!竟然能发现vs的Bug 
    楼主可以给 微软写封信。
      

  5.   

    typeof(MyEnumA[])的类型是Array,typeof(MyEnumB[])的类型也是Array。Type.IsAssignableFrom检查的时候发现它们的Type相同,所以返回了true。
      

  6.   

    我觉得类似此类的问题都是CLR的设计权限所引起,相信未来会完善的。
      

  7.   

    我的vs2005中经常会出现一条斜线,这肯定也是.net的一个bug
      

  8.   

    .net的bug还真不是一般地多呀,接分~
      

  9.   

    这个只需要鼠标点击那条线(对鼠标的操作要求可能比较高),然后再按Alt+F4,就可以把这条斜线干掉了另外,最近在做一个Entity类的自动copy,用于类似的Entity类之间的内容copy
    目前实现到下面的程度:        public class ReferenceTypeA
            {
                public string Name { get; set; }
                public ReferenceTypeA[] Children { get; set; }
            }        public class ReferenceTypeB
            {
                public string Name { get; set; }
                public ReferenceTypeB[] Children { get; set; }
            }        [TestMethod]
            public void ReferenceTypeAToReferenceTypeBTest()
            {
                EntityCopier copier = new ArrayCopierDecorator(EntityCopier.CreateAuto());
                #region Init a
                var a = new ReferenceTypeA[]
                {
                    new ReferenceTypeA
                    {
                        Name = "1",
                        Children = new ReferenceTypeA[]
                        {
                            new ReferenceTypeA
                            {
                                Name = "1.1",
                                Children = new ReferenceTypeA[]
                                {
                                    new ReferenceTypeA
                                    {
                                        Name = "1.1.1",
                                    } ,
                                    new ReferenceTypeA
                                    {
                                        Name = "1.1.2",
                                    } ,
                                }
                            } ,
                            new ReferenceTypeA
                            {
                                Name = "1.2",
                                Children = new ReferenceTypeA[]
                                {
                                    new ReferenceTypeA
                                    {
                                        Name = "1.2.1",
                                    } ,
                                    new ReferenceTypeA
                                    {
                                        Name = "1.2.2",
                                    } ,
                                }
                            } ,
                        }
                    } ,
                    new ReferenceTypeA
                    {
                        Name = "2",
                        Children = new ReferenceTypeA[]
                        {
                            new ReferenceTypeA
                            {
                                Name = "2.1",
                                Children = new ReferenceTypeA[]
                                {
                                    new ReferenceTypeA
                                    {
                                        Name = "2.1.1",
                                    } ,
                                    new ReferenceTypeA
                                    {
                                        Name = "2.1.2",
                                    } ,
                                }
                            } ,
                            new ReferenceTypeA
                            {
                                Name = "2.2",
                                Children = new ReferenceTypeA[]
                                {
                                    new ReferenceTypeA
                                    {
                                        Name = "2.2.1",
                                    } ,
                                    new ReferenceTypeA
                                    {
                                        Name = "2.2.2",
                                    } ,
                                }
                            } ,
                        }
                    } ,
                    new ReferenceTypeA
                    {
                        Name = "3",
                        Children = new ReferenceTypeA[]
                        {
                            new ReferenceTypeA
                            {
                                Name = "3.1",
                                Children = new ReferenceTypeA[]
                                {
                                    new ReferenceTypeA
                                    {
                                        Name = "3.1.1",
                                    } ,
                                    new ReferenceTypeA
                                    {
                                        Name = "3.1.2",
                                    } ,
                                }
                            } ,
                            new ReferenceTypeA
                            {
                                Name = "3.2",
                                Children = new ReferenceTypeA[]
                                {
                                    new ReferenceTypeA
                                    {
                                        Name = "3.2.1",
                                    } ,
                                    new ReferenceTypeA
                                    {
                                        Name = "3.2.2",
                                    } ,
                                }
                            } ,
                        }
                    } ,
                };
                #endregion
                ReferenceTypeB[] b = null;
                copier.Copy<ReferenceTypeA[], ReferenceTypeB[]>(a, ref b);
                #region Asserts
                Assert.AreEqual(a[0].Name, b[0].Name);
                Assert.AreEqual(a[0].Children[0].Name, b[0].Children[0].Name);
                Assert.AreEqual(a[0].Children[0].Children[0].Name, b[0].Children[0].Children[0].Name);
                Assert.AreEqual(a[0].Children[0].Children[1].Name, b[0].Children[0].Children[1].Name);
                Assert.AreEqual(a[0].Children[1].Name, b[0].Children[1].Name);
                Assert.AreEqual(a[0].Children[1].Children[0].Name, b[0].Children[1].Children[0].Name);
                Assert.AreEqual(a[0].Children[1].Children[1].Name, b[0].Children[1].Children[1].Name);
                
                Assert.AreEqual(a[1].Name, b[1].Name);
                Assert.AreEqual(a[1].Children[0].Name, b[1].Children[0].Name);
                Assert.AreEqual(a[1].Children[0].Children[0].Name, b[1].Children[0].Children[0].Name);
                Assert.AreEqual(a[1].Children[0].Children[1].Name, b[1].Children[0].Children[1].Name);
                Assert.AreEqual(a[1].Children[1].Name, b[1].Children[1].Name);
                Assert.AreEqual(a[1].Children[1].Children[0].Name, b[1].Children[1].Children[0].Name);
                Assert.AreEqual(a[1].Children[1].Children[1].Name, b[1].Children[1].Children[1].Name);            Assert.AreEqual(a[2].Name, b[2].Name);
                Assert.AreEqual(a[2].Children[0].Name, b[2].Children[0].Name);
                Assert.AreEqual(a[2].Children[0].Children[0].Name, b[2].Children[0].Children[0].Name);
                Assert.AreEqual(a[2].Children[0].Children[1].Name, b[2].Children[0].Children[1].Name);
                Assert.AreEqual(a[2].Children[1].Name, b[2].Children[1].Name);
                Assert.AreEqual(a[2].Children[1].Children[0].Name, b[2].Children[1].Children[0].Name);
                Assert.AreEqual(a[2].Children[1].Children[1].Name, b[2].Children[1].Children[1].Name);
                #endregion
            }
      

  10.   

    bool b = typeof(MyEnumB[]).IsAssignableFrom(typeof(MyEnumA[]));  // true, because Array
    bool c = typeof(MyEnumB).IsAssignableFrom(typeof(MyEnumA));      // false
      

  11.   

    bool b = typeof(MyEnumB[]).IsAssignableFrom(typeof(MyEnumA[]));  // true, because Array
    bool c = typeof(MyEnumB).IsAssignableFrom(typeof(MyEnumA));      // false
      

  12.   

    发现这个问题还能扩展
    bool b = typeof(uint[]).IsAssignableFrom(typeof(int[])); // trueuint[] array = new int[10]; //Error Cannot implicitly convert type 'int[]' to 'uint[]'uint[] array = (uint[])new int[10]; //Error Cannot convert type 'int[]' to 'uint[]'
      

  13.   

    多谢楼主,再出现的时候试试,你用Alt+F4,好像是把那条线当作窗口,确实没有想到这样处理就能搞定。
      

  14.   

    如果谁有空的话,看看微软放出来的源代码有没有相关内容吧。感觉函数名字有Assignable,而且还允许子类override,肯定会有可以Assign过去的方法——肯定不是指的隐式转换和显式转换吧。
      

  15.   

    bool IsAssignableFrom (
    Type c
    )
     参数
    c
    与当前的 Type 进行比较的 Type。返回值
    如果 c 和当前 Type 表示相同的类型,或者当前 Type 位于 c 的继承层次结构中,或者当前 Type 是 c 所实现的接口,或者 c 是一个泛型类型参数并且当前 Type 表示 c 的约束之一,则为 true。如果这些条件都不成立,或者 c 为空引用(在 Visual Basic 中为 Nothing),则为 false。
      

  16.   

    enum实际上是 enum:int也就是说可以看成是int类型的,所以在数组的时候就看成了int[]就是true了以上是我的推断,这东西确实挺恶心的,感谢楼主提醒
      

  17.   

    无法解释
    bool b = typeof(string[]).IsAssignableFrom(typeof(int[])); // false
      

  18.   

    Framework 2.0,以及基于2.0的3.0,3.5都有这个问题
    1.0,1.1没测试过
      

  19.   

    Enum本质上应该是被看做了int吧?
      

  20.   

    LZ测试下这段程序再来说这是不是bug            object enums = new MyEnumA[] { MyEnumA.A, MyEnumA.B, MyEnumA.C };
                MyEnumB[] enumsB = (MyEnumB[])enums;
                foreach (MyEnumB enumB in enumsB)
                {
                    Console.WriteLine(enumB);
                }
      

  21.   

    要使用反射的话对Array,Enum,GenericType,Struct等概念都要比较熟悉才行的,否则很多地方会出现这种无法理解的问题。
      

  22.   

    枚举类型在编译时,对枚举中各个值的所有引用均将转换为数值文本。每种枚举类型都有基础类型,该类型可以是除 char 以外的任何整型。枚举元素的默认基础类型为 int。默认情况下,第一个枚举数的值为 0,后面每个枚举数的值依次递增 1。public enum MyEnumA { A, B, C, }
    public enum MyEnumB { X, Y, Z, }编译后为...MyEnumA { '0', '1', '2', }
    MyEnumB { '0', '1', '2', }不是.NET的bug...是lz的bug...