c# - object and collection initializer

Since the .net 4.0 there introduce the concept of object initializer and collection initializer. They are especially handy to cut the amount of code to write expiclity and delegate the work to Compiler. 

 

Object Initializer 

 

 

 

  class Cat
  {
    public int Age { get; set; }
    public string Name { get; set; }
  }

public class Program 
{
  public static void Main(string[] args) 
  {
       Cat cat = new Cat { Age = 10, Name = "Fluffy" };
  } 

}
 

 

 

In LINQ, where you can use the Object initializer with anonymous types, which alows you to do the projection and others quite easily.

 

 

      var pet = new { Age = 10, Name = "Fluffy" }; // it is especially useful in LINQ eury expression
 

 

 

 

Collection Initializer 

 

Collection initializer will allow you to initialize an array .e.g Cat[] or a List<Cat> quick easily. generally you can do 

 

 

      List<Cat> cats = new List<Cat>
      {
        new Cat{ Name = "Sylvester", Age=8 },
        new Cat{ Name = "Whiskers", Age=2 },
        new Cat{ Name = "Sasha", Age=14 }
      };
 

But if you like, you can use the more cannonical way of constructing collections with constructor parenthesis appended . 

 

      List<Cat> cats2 = new List<Cat>()
      {
        new Cat(){ Name = "Sylvester", Age=8 },
        new Cat(){ Name = "Whiskers", Age=2 },
        new Cat(){ Name = "Sasha", Age=14 }
      };
 

and if you are using an array, you can even omit the type in after the new keyword. 

 

      Cat[] cats3 = new []{ 
        new Cat(){ Name = "Sylvester", Age=8 },
        new Cat(){ Name = "Whiskers", Age=2 },
        new Cat(){ Name = "Sasha", Age=14 }
      };

 

 

Below is the full code that I used to test the full Object initializer and Collection Initializer things. 

 

 

namespace ObjectCollectionInitializer
{

  // Demo the use of Object initalizer
  // where you have the form of 
  //  Cat cat = new Cat { Age = 10, Age = "Fluffy" } ;
  class Cat
  {
    public int Age { get; set; }
    public string Name { get; set; }
  }




  public class Program
  {
    public static void Main(string[] args)
    {
      Cat cat = new Cat { Age = 10, Name = "Fluffy" };
      var pet = new { Age = 10, Name = "Fluffy" }; // it is especially useful in LINQ eury expression


      List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
      // and you can still keep the () operator 
      List<int> digits2 = new List<int> { 0 + 1, 12 % 3, MakeInt() };


      // Demo the use of Collection initializer
      // the collection initializer is a syntax sugar that allows you to 
      // add a set of objects to a collection.
      // the basic form of a Collection Initializer is as follow.
      //    List<Cat> cats = new List<Cat> {
      //       new Cat { Age = 10, Name = "Fluffy" },
      //       ...
      //    }
      // the same is true for object 
      List<Cat> cats = new List<Cat>
      {
        new Cat{ Name = "Sylvester", Age=8 },
        new Cat{ Name = "Whiskers", Age=2 },
        new Cat{ Name = "Sasha", Age=14 }
      };
      // or if you prefer, you can use the cannonical way (with () )
      List<Cat> cats2 = new List<Cat>()
      {
        new Cat(){ Name = "Sylvester", Age=8 },
        new Cat(){ Name = "Whiskers", Age=2 },
        new Cat(){ Name = "Sasha", Age=14 }
      };

      // if the collection is an array and 
      // if it is the same type, you can omit the types as well 
      Cat[] cats3 = new []{ 
        new Cat(){ Name = "Sylvester", Age=8 },
        new Cat(){ Name = "Whiskers", Age=2 },
        new Cat(){ Name = "Sasha", Age=14 }
      };
    }


    public static int MakeInt()
    {
      return 0;
    }
  }
}
 

 

References: 

you can refer "Object and Collection Initializer (C# Programming Guide)"

'------------------------------------------------------------------+ ' Module specification '------------------------------------------------------------------+ ' ' Module Name : ExpWStoQL ' ' Copyright : Yokogawa SCE, 2004 ' ' Author : Jan Worst ' ' Description : Export Worksheet to Quickload file ' ' '------------------------------------------------------------------+ ' Changes .... '------------------------------------------------------------------+ ' Who When Change What '------------------------------------------------------------------+ ' WST Jun-04 exxxx FAST/TOOLS to Excel demo ' WST Oct-05 Add comment column (starting with "#") '------------------------------------------------------------------+ Option Explicit Dim qldws As New qldWorkSheet Dim myWS As New Excel.Worksheet Dim wsAbs As wsAbstract Dim ColInstall As Integer Dim ColUnit As Integer Dim ColTag As Integer Dim ColSub As Integer Dim ColGroupName As Integer Dim ComposedKey As Boolean ' Indicates NAME field missing Dim colQldFields As Collection Dim ColSelected(256) As Boolean ' Shows if column must be exported Dim wsM As WsMacros Public Sub ExpWStoQL(ws As Excel.Worksheet, _ qlFile As String, _ Append As Boolean, _ SelectedRowsOnly As Boolean, _ SelectedColumnsOnly As Boolean, _ WriteDummyLines As Boolean) Dim Row As Long Dim i As Long Dim Column As Integer Application.ScreenUpdating = False qldws.Initialize ws Set myWS = ws Set wsM = New WsMacros Set wsAbs = New wsAbstract wsAbs.Initialize ws '---------------------------------------------------------- ' Open Quickload file '---------------------------------------------------------- If Append Then Open qlFile For Append As #1 Else Open qlFile For Output As #1 End If On Error GoTo ExportError Print #1, "!-----------------------------------------------------------------------" Print #1, "! Quickload file : " & qlFile Print #1, "! From workbook : " & ActiveWorkbook.FullName Print #1, "! Sheet : " & ActiveSheet.Name Print #1, "! Generated : " & FormatDateTime(Now, vbLongDate) & " " & _ FormatDateTime(Now, vbLongTime) Print #1, "! By : " & Environ("username") & "@" & Environ("computername") Print #1, "!-----------------------------------------------------------------------" Print #1, "" '---------------------------------------------------------- ' Write text "@FIELDS" '---------------------------------------------------------- Print #1, "@FIELDS" '---------------------------------------------------------- ' Check if key (NAME) field must bo composed from ' fields INSTALL, UNIT, TAG, SUB '---------------------------------------------------------- GetQuickloadFields SelectedColumnsOnly '---------------------------------------------------------- ' Write Recordset Fields '---------------------------------------------------------- Dim FirstColumnWritten As Boolean For i = 1 To colQldFields.count If Left$(colQldFields.Item(i), 1) <> "#" Then ' not a comment column If FirstColumnWritten = False Then FirstColumnWritten = True Else Print #1, ", "; End If PrintHeaderMacro colQldFields.Item(i), qldws.RowDataHeader End If Next i '---------------------------------------------------------- ' Write text "@<dataset name>" '---------------------------------------------------------- Print #1, "" Print #1, "@" & qldws.DatasetName '---------------------------------------------------------- ' Write all records ' (do not write rows that are hidden by the "Excel Autofilter" '---------------------------------------------------------- For Row = qldws.RowDataFirst To qldws.RowDataLast If Not SelectedRowsOnly Or wsAbs.RowSelected(Row) Then OneRow Row, SelectedColumnsOnly ElseIf WriteDummyLines Then Print #1, " " End If Next Row '---------------------------------------------------------- ' Close Quickload file '---------------------------------------------------------- Print #1, "" Close #1 Set qldws = Nothing Set wsM = Nothing Application.ScreenUpdating = True Set wsAbs = Nothing Exit Sub ExportError: Close #1 Application.ScreenUpdating = True Set wsM = Nothing Set qldws = Nothing Set wsAbs = Nothing ' propagate error Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext End Sub '---------------------------------------------------------- ' Write one row '---------------------------------------------------------- Private Sub OneRow(Row As Long, SelectedColumnsOnly As Boolean) Dim FirstColumnWritten As Boolean Dim Column As Integer Dim ws As Worksheet Set ws = qldws.Worksheet FirstColumnWritten = False '----------------------------------------- ' Write composed key field '----------------------------------------- If ComposedKey Then PrintFieldMacro "", qldws.getKeyValue(Row), Row FirstColumnWritten = True End If '----------------------------------------- ' Write composed key field '----------------------------------------- For Column = 1 To qldws.ColumnCount ' Debug.Print Column, ws.Cells(qldws.RowDataHeader, Column), ws.Cells(Row, Column), Row If Left$(ws.Cells(qldws.RowDataHeader, Column), 1) <> "#" Then ' not a comment column ' If Not SelectedColumnsOnly Or _ ' (SelectedColumnsOnly And _ ' Not Intersect(Selection, myWs.Cells(qldws.RowDataHeader, Column)) Is Nothing) Then If ColSelected(Column) Then If (Not ComposedKey Or ( _ ComposedKey And _ qldws.IsSplitNameField(ws.Cells(qldws.RowDataHeader, Column)) = False And _ UCase$(ws.Cells(qldws.RowDataHeader, Column)) <> "NAME")) Then If FirstColumnWritten = False Then FirstColumnWritten = True Else Print #1, ", "; End If PrintFieldMacro ws.Cells(qldws.RowDataHeader, Column), ws.Cells(Row, Column), Row End If End If End If Next Column Print #1, "" End Sub '---------------------------------------------------------- ' Evaluate Header macro '---------------------------------------------------------- Private Sub PrintHeaderMacro(ByVal CellContents As String, Row As Long) CellContents = Trim$(CellContents) If Left$(CellContents, 1) = "$" Then Dim i As Integer On Error GoTo HeaderMacroNotFound With wsM.HeaderMacro(CellContents) For i = 1 To .FieldCount Print #1, .Field(i); If i <> .FieldCount Then Print #1, ", "; End If Next i End With Else If CellContents = "<none>" Then CellContents = "" Print #1, CellContents; End If Exit Sub HeaderMacroNotFound: On Error GoTo ItemNameMacroNotFound Print #1, wsM.ItemNameMacro(CellContents).Field; Exit Sub ItemNameMacroNotFound: ' Throw error Err.Raise Err.Number, Err.Source, _ Err.Description & vbCrLf & vbCrLf & "Cannot evaluate macro" & CellContents, _ Err.HelpFile, Err.HelpContext End Sub '---------------------------------------------------------- ' Evaluate Field macro '---------------------------------------------------------- Private Sub PrintFieldMacro(HeaderMacroName As String, ByVal CellContents As String, Row As Long) CellContents = Trim$(CellContents) If Left$(CellContents, 1) = "$" Then Dim i As Integer On Error GoTo HeaderMacroNotFound With wsM.HeaderMacro(HeaderMacroName).FieldMacro(CellContents) For i = 1 To .FieldCount Print #1, """" & .Field(i) & """"; If i <> .FieldCount Then Print #1, ", "; End If Next i End With Else If CellContents = "<none>" Then CellContents = "" Print #1, """" & CellContents & """"; End If Exit Sub HeaderMacroNotFound: On Error GoTo ItemNameMacroNotFound Print #1, """" & CellContents & """"; Exit Sub ItemNameMacroNotFound: ' Throw error Err.Raise Err.Number, Err.Source, _ Err.Description & vbCrLf & vbCrLf & "Cannot evaluate macro" & CellContents, _ Err.HelpFile, Err.HelpContext End Sub '-------------------------------------------------------------------- ' Get quickload field names ' normally they correspond with the Excel header fields, exceptions are ' made for "composed keys" for UNIT_DF, ITEM_DEF, etc. ' ' Outputs: ComposedKey - indicates that key is composed ' colQldFields - collection of fields written to Quickload file ' '-------------------------------------------------------------------- Private Sub GetQuickloadFields(SelectedColumnsOnly As Boolean) Set colQldFields = New Collection ComposedKey = True ' assume True Dim col As Long '---------------------------------------------------------- ' Check if key (NAME) field must bo composed from ' fields INSTALL, UNIT, TAG, SUB '---------------------------------------------------------- ComposedKey = qldws.hasSplitName ColInstall = qldws.ColFieldName("INSTALL") ColUnit = qldws.ColFieldName("UNIT") ColTag = qldws.ColFieldName("TAG") ColSub = qldws.ColFieldName("SUB") ColGroupName = qldws.ColFieldName("GROUP_NAME") '---------------------------------------------------------- ' Fill Fields collection '---------------------------------------------------------- If ComposedKey Then colQldFields.Add "NAME" End If Dim FieldContents As String Dim R As Range For col = 1 To qldws.ColumnCount ' Find out about selected columns FieldContents = "" ColSelected(col) = True If SelectedColumnsOnly Then Set R = Intersect(Selection, myWS.Cells(qldws.RowDataHeader, col)) If R Is Nothing Then FieldContents = "#" ' fake commment column ColSelected(col) = False End If End If FieldContents = FieldContents & UCase$(qldws.Worksheet.Cells(qldws.RowDataHeader, col)) If ComposedKey Then If col <> ColInstall And _ col <> ColUnit And _ col <> ColTag And _ col <> ColSub And _ col <> ColGroupName Then colQldFields.Add FieldContents End If Else colQldFields.Add FieldContents End If Next col End Sub '--------------------------------------- ' Read Shift-JIS and Write UTF-8N '--------------------------------------- Public Sub WriteUTF8N(strFilename As String) Dim objReadStream As Object Dim objWriteStream As Object Dim bytData() As Byte Const adTypeText = 2 Const adTypeBinary = 1 Const adReadLine = -2 Const adWriteLine = 1 Const adCRLF = -1 Const adSaveCreateOverWrite = 2 Set objReadStream = CreateObject("ADODB.Stream") Set objWriteStream = CreateObject("ADODB.Stream") With objReadStream .Open .Type = adTypeText .Charset = "GB2312" .LineSeparator = adCRLF .LoadFromFile strFilename End With With objWriteStream .Open .Type = adTypeText .Charset = "UTF-8" .LineSeparator = adCRLF End With Do Until objReadStream.EOS objWriteStream.WriteText objReadStream.ReadText(adReadLine), adWriteLine Loop objReadStream.Close With objWriteStream .Position = 0 .Type = adTypeBinary .Position = 3 bytData = .Read .Close .Open .Position = 0 .Type = adTypeBinary .Write bytData .SaveToFile strFilename, adSaveCreateOverWrite ' .SaveToFile strFilename & ".txt", adSaveCreateOverWrite .Close End With End Sub 用VS编写C#程序
05-17
<think>我们正在处理一个C#编程问题:如何将集合传递到子窗体。根据引用资料,我们可以使用多种方法,包括事件、委托、接口等。同时,引用中提到了使用WindowsAPI的方法,但更常见的是使用C#内置的机制。分析需求:将集合(例如List<T>)从父窗体传递到子窗体。方法选择:1.通过子窗体的构造函数传递:这是最直接的方式,在创建子窗体时将集合作为参数传入。2.通过公开属性传递:创建子窗体后,通过设置子窗体的一个公共属性来传递集合。3.通过事件或委托:父窗体触发事件,子窗体订阅该事件来接收数据。但这里传递集合是一次性的,所以前两种方法更直接。4.通过接口:如引用[2]中,子窗体实现了某个接口,父窗体调用该接口的方法传递数据。但这里我们不需要那么复杂,因为只是传递数据而非消息通信。考虑到简单性,我们推荐使用构造函数或属性。步骤:方法1:通过构造函数传递-在子窗体中定义一个构造函数,接收集合参数。-父窗体在创建子窗体实例时传入集合。方法2:通过属性传递-在子窗体中定义一个公共属性,类型与集合匹配。-父窗体在创建子窗体实例后,给该属性赋值。另外,引用[1]提到使用委托和事件,引用[3]提到使用WindowsAPI,但这些对于简单的数据传递来说过于复杂。因此,我们选择两种简单的方法进行说明。示例:假设我们有一个父窗体MainForm和一个子窗体ChildForm,需要传递一个List<string>集合。方法1:构造函数传递子窗体代码:```csharppublicpartial classChildForm: Form{private List<string>_data;//构造函数接收集合publicChildForm(List<string> data){InitializeComponent();_data= data;}//在窗体加载时使用数据,例如显示在ListBox中privatevoid ChildForm_Load(objectsender,EventArgs e){listBox1.DataSource =_data;}}```父窗体中打开子窗体:```csharpList<string>myList= newList<string> {"item1","item2","item3"};ChildFormchildForm= newChildForm(myList);childForm.Show();```方法2:通过属性传递子窗体代码:```csharppublic partialclass ChildForm :Form{//公共属性publicList<string> Data{ get; set; }publicChildForm(){InitializeComponent();}private voidChildForm_Load(object sender, EventArgse){//使用属性Dataif (Data !=null){listBox1.DataSource= Data;}}}```父窗体中:```csharpList<string> myList =new List<string>{ "item1", "item2", "item3" };ChildForm childForm =new ChildForm();childForm.Data= myList;childForm.Show();```注意:在方法2中,我们假设在窗体加载事件中使用数据。如果窗体已经显示,赋值属性后可能需要手动刷新控件。引用[4]提到要关注性能、稳定性和用户体验。这里两种方法都是直接传递引用,效率较高。但要注意,如果集合很大,且子窗体只是读取,那么没有问题。如果子窗体要修改集合,并且希望父窗体同步,那么需要考虑使用可观察的集合(如ObservableCollection)或事件通知。根据引用[3]的简介,我们也可以使用事件或委托,但上述两种方法更简单直接。因此,我们推荐使用构造函数或属性传递集合。相关问题:1.如果子窗体需要修改集合并反馈给父窗体,应该怎么做?2.传递大型集合时有哪些性能考虑?3.如何确保子窗体使用的集合是线程安全的?</think>在 C# 中将集合传递到子窗体可以通过以下方法实现,结合引用资料提供三种推荐方案: ### 方法 1:通过构造函数传递(最常用) ```csharp // 子窗体代码 public partial class ChildForm : Form { private List<string> _dataCollection; // 构造函数接收集合 public ChildForm(List<string> data) { InitializeComponent(); _dataCollection = data; // 存储传递的集合 } private void ChildForm_Load(object sender, EventArgs e) { dataGridView1.DataSource = _dataCollection; // 使用集合 } } // 父窗体调用 List<string> myList = new List<string> { "A", "B", "C" }; ChildForm child = new ChildForm(myList); // 通过构造函数传递 child.Show(); ``` ### 方法 2:通过公共属性传递 ```csharp // 子窗体代码 public partial class ChildForm : Form { public List<string> DataCollection { get; set; } // 公共属性 private void ChildForm_Load(object sender, EventArgs e) { listBox1.DataSource = DataCollection; // 使用属性 } } // 父窗体调用 ChildForm child = new ChildForm(); child.DataCollection = myList; // 设置属性后显示 child.Show(); ``` ### 方法 3:通过接口实现消息传递(引用[2][3]) ```csharp // 定义接口 public interface IDataReceiver { void ReceiveData(List<string> data); } // 子窗体实现接口 public partial class ChildForm : Form, IDataReceiver { public void ReceiveData(List<string> data) { comboBox1.DataSource = data; // 实现数据接收 } } // 父窗体传递数据 var child = new ChildForm(); child.Show(); ((IDataReceiver)child).ReceiveData(myList); // 通过接口传递 ``` ### 最佳实践建议 1. **简单数据**:优先使用构造函数或属性传递 2. **实时更新**:需双向通信时采用接口/事件模式(引用[3]) 3. **大型数据**:传递集合引用而非副本以提高性能(引用[4]) 4. **类型安全**:使用泛型集合如`List<T>`替代`ArrayList` > 关键点:窗体间传递集合本质是对象引用传递,子窗体可直接操作原始集合(修改会反映到父窗体)。若需隔离数据,传递时创建新集合:`new List<T>(originalCollection)`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值