【问题标题】:Is this possible using generics? c#这可能使用泛型吗? C#
【发布时间】:2011-04-20 21:40:08
【问题描述】:

我知道我可以通过创建自定义类来解决以下问题,但是可以将以下内容强类型化为List(或任何其他类型)吗?

 var x = new object[] 
        { 
            new object[] { new Image(), new TextBox(), new FileUpload() }, 
            new object[] { new Image(), new TextBox() , new FileUpload()} 
        };

以上代码中的对象类型只是举例。

一天结束了,我的大脑有点软了。

编辑:元组?

【问题讨论】:

    标签: c# generics list collections strong-typing


    【解决方案1】:

    是的,通用元组可以工作:

    http://sankarsan.wordpress.com/2009/11/29/tuple-in-c-4-0/

    var myTuples = new List<Tuple<type1, type2, type3>>();
    

    【讨论】:

    • 不错!另一个我为什么喜欢浏览stackoverflow的例子......每天学习新东西。永远不知道元组...
    【解决方案2】:
    var x = new []         
    {             
        new 
        { 
            Image = new Image(), 
            TextBox = new TextBox(), 
            FileUpload = new FileUpload() 
        },
        new 
        { 
            Image = new Image(), 
            TextBox = new TextBox(), 
            FileUpload = new FileUpload()
        }         
    };
    

    【讨论】:

    • 虽然子数组会更好,例如新 { Image = ..., TextBox = ... 等
    • 是的,我也在尝试编辑以添加它......代码格式化程序似乎很糟糕......每次我想添加代码时,它都会将占位符粘贴在我不希望它出现的地方。
    【解决方案3】:

    您没有指定,但看起来您使用的是 System.Web 中的类型?如果是这样,那么可以使用泛型来创建更强类型的集合。例如

    List<List<WebControl>> list = new List<List<WebControl>>();
    list.Add(new List<WebControl>(new WebControl()[] new Image(), new TextBox(), new FileUpload
    () );
    list.Add(new List<WebControl>(new WebControl()[] new Image(), new TextBox(), new FileUpload() );
    

    为了获得一个非常强类型的集合,尽管您需要使用Tuple&lt;&gt; 或匿名类型解决方案。

    【讨论】:

      【解决方案4】:

      你可以像你说的那样使用元组。或匿名类型:

      var x = new[] 
          { 
              new { Image = new Image(), TextBox = new TextBox(), FileUpload = new FileUpload() }, 
              new { Image = new Image(), TextBox = new TextBox(), FileUpload = new FileUpload() }
          };
      

      【讨论】:

        【解决方案5】:

        匿名对象强类型的。 唯一担心的是您无法知道类型名称(不是直接)。

        举个例子(如果太长见谅):

                static void T2( )
            {
                var x = new
                {
                    a = new { a1 = new Type1( "x.1" ), a2 = new Type2( 1 ), a3 = new Type3( '1' ) },
                    b = new { b1 = new Type1( "x.2" ), b2 = new Type2( 2 ), b3 = new Type3( '2' ) }
                };
        
                var y = new
                {
                    a = new { a1 = new Type1( "y.1" ), a2 = new Type2( 1 ), a3 = new Type3( '1' ) },
                    b = new { b1 = new Type1( "y.2" ), b2 = new Type2( 2 ), b3 = new Type3( '2' ) }
                };
        
                var z = new
                {
                    a = new { a1 = new Type1( "y.1" ), a2 = new Type3( '1' ) },
                    b = new { b1 = new Type3( 'z' ), b2 = new Type2( 2 ) }
                };
        
                Console.WriteLine( new string( '-', 40 ) );
                Console.WriteLine( "Anonymous object \"x\" is named {0}.", x.GetType( ) );
                Console.WriteLine( "Anonymous object \"y\" is named {0}.", y.GetType( ) );
                Console.WriteLine( "Anonymous object \"z\" is named {0}.", z.GetType( ) );
        
                Console.WriteLine( new string( '-', 40 ) );
                Console.Write( "Anonymous object \"x\" == \"y\"? " );
                Console.WriteLine( x.Equals( y ) ? "Yes" : "No" );
        
                Console.Write( "Anonymous object \"x\" == \"z\"? " );
                Console.WriteLine( x.Equals( z ) ? "Yes" : "No" );
        
                var x2 = new
                {
                    a = new { a1 = new Type1( "x.1" ), a2 = new Type2( 1 ), a3 = new Type3( '1' ) },
                    b = new { b1 = new Type1( "x.2" ), b2 = new Type2( 2 ), b3 = new Type3( '2' ) }
                };
        
                Console.Write( "Anonymous object \"x\" == \"x2\"? " );
                Console.WriteLine( x.Equals( x2 ) ? "Yes" : "No" );
        
                // Uncomment it to give:
                //Error 1   Cannot implicitly convert type 'AnonymousType#1' to 'AnonymousType#2'
        #if GiveMeAnError
                z = new
                {
                    a = new { a1 = new Type1( "z.1" ), a2 = new Type2( 1 ), a3 = new Type3( '1' ) },
                    b = new { b1 = new Type1( "z.2" ), b2 = new Type2( 2 ), b3 = new Type3( '2' ) }
                };
        
                Console.WriteLine( "Anonymous object \"z\" now is named {0}.", z.GetType( ) );
        
                Console.Write( "Anonymous object \"x\" == \"z\"? " );
                Console.WriteLine( x.Equals( z ) ? "Yes" : "No" );
        #endif
                Console.ReadKey( );
            }
        

        它输出:

        /*----------------------------------------
        Anonymous object "x" is named <>f__AnonymousType2`2[<>f__AnonymousType0`3    [anon_obj.Type1,anon_obj.Type2,anon_obj.Type3],<>f__AnonymousType1`3[anon_obj.Type1,anon_obj.Type2,anon_obj.Type3]].
        Anonymous object "y" is named <>f__AnonymousType2`2[<>f__AnonymousType0`3[anon_obj.Type1,anon_obj.Type2,anon_obj.Type3],<>f__AnonymousType1`3[anon_obj.Type1,anon_obj.Type2,anon_obj.Type3]].
        Anonymous object "z" is named <>f__AnonymousType2`2[<>f__AnonymousType3`2[anon_obj.Type1,anon_obj.Type3],<>f__AnonymousType4`2[anon_obj.Type3,anon_obj.Type2]].
        ----------------------------------------
        Anonymous object "x" == "y"? No
        Anonymous object "x" == "z"? No
        Anonymous object "x" == "x2"? Yes*/
        

        每个匿名对象组合都有自己的名称并定义一个唯一的类型。 使用相同类型和类型名称声明的对象属于相同类型,如“x == x2”。

        不过,最初的示例很棘手,因为它定义了“object[]”数组,其中包含“object[]”数组。 这边

                    var x = new object[ ]  
                {  
                    new object[] { new Type1("x.1"), new Type2(1), new Type3('1') },  
                    new object[] { new Type1("x.2"), new Type2(2) , new Type3('2')}  
                };
        
                var y = new object[ ]  
                {  
                    new object[] { new Type1("y.1"), new Type2(1), new Type3('1') },  
                    new object[] { new Type1("y.2"), new Type2(2) , new Type3('2')}  
                };
        
                var z = new object[ ]  
                {  
                    new object[] { new Type1("y.1"), new Type3('1') },  
                    new object[] { new Type3('z'), new Type2(2)}  
                };
        

        都将是相同的type(object[]),并且比较总是通过比较pointers来完成,希望会有所不同。

                static void T1( )
            {
                var x = new object[ ]  
                {  
                    new object[] { new Type1("x.1"), new Type2(1), new Type3('1') },  
                    new object[] { new Type1("x.2"), new Type2(2) , new Type3('2')}  
                };
        
                var y = new object[ ]  
                {  
                    new object[] { new Type1("y.1"), new Type2(1), new Type3('1') },  
                    new object[] { new Type1("y.2"), new Type2(2) , new Type3('2')}  
                };
        
                var z = new object[ ]  
                {  
                    new object[] { new Type1("y.1"), new Type3('1') },  
                    new object[] { new Type3('z'), new Type2(2)}  
                };
        
                Console.WriteLine( new string( '-', 40 ) );
                Console.WriteLine( "Anonymous object \"x\" is named {0}.", x.GetType( ) );
                Console.WriteLine( "Anonymous object \"y\" is named {0}.", y.GetType( ) );
                Console.WriteLine( "Anonymous object \"z\" is named {0}.", z.GetType( ) );
        
        
                Console.WriteLine( new string( '-', 40 ) );
                Console.Write( "Anonymous object \"x\" == \"y\"? " );
                Console.WriteLine( x.Equals( y ) ? "Yes" : "No" );
        
                Console.Write( "Anonymous object \"x\" == \"z\"? " );
                Console.WriteLine( x.Equals( z ) ? "Yes" : "No" );
        
                var x2 = new object[ ]  
                {  
                    new object[] { new Type1("x.1"), new Type2(1), new Type3('1') },  
                    new object[] { new Type1("x.2"), new Type2(2) , new Type3('2')}  
                };
        
                Console.Write( "Anonymous object \"x\" == \"x2\"? " );
                Console.WriteLine( x.Equals( x2 ) ? "Yes" : "No" );
        
                z = new object[ ]  
                {  
                    new object[] { new Type1("x.1"), new Type2(1), new Type3('1') },  
                    new object[] { new Type1("x.2"), new Type2(2) , new Type3('2')}  
                };
        
                Console.WriteLine( "Anonymous object \"z\" now is named {0}.", z.GetType( ) );
        
        
                Console.Write( "Anonymous object \"x\" == \"z\"? " );
                Console.WriteLine( x.Equals( z ) ? "Yes" : "No" );
        
                Console.Write( "Anonymous object \"x\" == \"z\" (memberwise)? " );
                Console.WriteLine(
                    x[ 0 ].Equals( z[ 0 ] )
                    && x[ 1 ].Equals( z[ 1 ] )
                    ? "Yes" : "No" );
        
                Console.ReadKey( );
            }
        

        将输出:

        /*----------------------------------------
        Anonymous object "x" is named System.Object[].
        Anonymous object "y" is named System.Object[].
        Anonymous object "z" is named System.Object[].
        ----------------------------------------
        Anonymous object "x" == "y"? No
        Anonymous object "x" == "z"? No
        Anonymous object "x" == "x2"? No
        Anonymous object "z" now is named System.Object[].
        Anonymous object "x" == "z"? No
        Anonymous object "x" == "z" (memberwise)? No
        ----------------------------------------*/
        

        看到问题了吗?

        【讨论】:

          【解决方案6】:

          如果您使用的是框架 4,Tuple&lt;Image, TextBox, FileUpload&gt;[]List&lt;Tuple&lt;Image, TextBox, FileUpload&gt;&gt; 就可以解决问题。

          否则,您可以使用匿名类型,但除此之外可能会很尴尬(因为在有用的情况下您不能声明类型)。

          最后,自行开发并不是最棘手的结构。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-04-20
            • 2011-04-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-12
            • 2021-05-17
            相关资源
            最近更新 更多