VB to C# Reflections

PiggyBank1974

Newcomer
Joined
Sep 28, 2004
Messages
9
Hi There,

As I know VB.net miles better than C# I've been creating a Dll that will handle a SQLCE database on a windows mobile device.

I have most of it working ok But I'm trying to convert this method below for VB(Full .net framework), to Compact framework using C#

But I'm a little stuck.

The idea of the function is to use reflection and fill a custom ListviewItems class with information from the database this works great in Full .net framework, but not in CE so far.

VB.net version is:

Visual Basic:
     Public Function GetRecords(ByVal MSLV As Object, ByVal Query As String, ByVal T As Type) As List(Of Windows.Forms.ListViewItem)
     Dim mProperty As PropertyInfo
     Dim mList As List(Of ListViewItem) = New List(Of ListViewItem)
     Dim Da As OleDbDataAdapter = New OleDbDataAdapter(Query, mDbConnection)
     Dim Ds As DataSet = New DataSet("Blank")

      Da.Fill(Ds, "Blank")

      For Each table As DataTable In Ds.Tables
       For Each row As DataRow In table.Rows
        Dim mobj As Object = Activator.CreateInstance(T)

         ' If the first column is the same as the for column in the row set the text.
         If MSLV.Columns(0).Tag = table.Columns.Item(0).ColumnName Then
           mobj.text = row(table.Columns.Item(0).ColumnName)
         End If

          For Each LVColumn As System.Windows.Forms.ColumnHeader In MSLV.Columns
           ' Skip the first column as this is the items column not the sub  items column.
           If MSLV.Columns(0).Tag <> LVColumn.Tag Then
            ' Make sure the column is in the row columns list or it will fail.
            If row.Table.Columns.Contains(LVColumn.Tag) = True Then
              mobj.subitems.add(row(LVColumn.Tag))
            End If
           End If
          Next LVColumn

         For Each column As DataColumn In table.Columns
            mProperty = T.GetProperty(column.ColumnName)

            If mProperty IsNot Nothing Then
              mProperty.SetValue(mobj, row(column.ColumnName), Nothing)
            End If
         Next column

         mList.Add(mobj)
       Next row
      Next table

     Return mList
     End Function

C# version

Visual Basic:
  public List<ListViewItem> GetRecords(Object MSLV, string Query, Type T)
  {
   if (mSqlCeConnection.State == System.Data.ConnectionState.Open)
   {
    PropertyInfo mProperty;
    List<ListViewItem> mList = new List<ListViewItem>();
    SqlCeDataAdapter DA = new SqlCeDataAdapter(Query, mSqlCeConnection);
    DataSet DS = new DataSet("Blank");

    DA.Fill(DS, "Blank");

    foreach (DataTable table in DS.Tables)
    {
     foreach (DataRow row in table.Rows)
     {
      Object mobj = Activator.CreateInstance(T);

      // If the first column is the same as the for column in the row set the text. 
      if (MSLV.Columns[0].Text == table.Columns[0].ColumnName)
      {
       mobj.Text = row[table.Columns[0].ColumnName];
      }

      foreach (ColumnHeader LVColumn in MSLV.Columns)
      {
       // Skip the first column as this is the items column not the sub  items column.

       if (MSLV.Columns[0].Text != LVColumn.Text)
       {
        // Make sure the column is in the row columns list or it will fail.
        if (row.Table.Columns.Contains(LVColumn.Text) == true)
        {
         mobj.SubItems.Add(row[LVColumn.Text]);
        }
       }
      }

      foreach (DataColumn column in table.Columns)
      {
       mProperty = T.GetProperty(column.ColumnName);

       if (mProperty != null)
       {
        mProperty.SetValue(mobj, row[column.ColumnName], null);
       }
      }

      mList.Add(mobj);
     }
    }

    return mList;
   }
   return null;
  }

The problem is on the C# version it errors on these

'object' does not contain a definition for 'Columns' and no extension method 'Columns' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
'object' does not contain a definition for 'Text' and no extension method 'Text' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

'object' does not contain a definition for 'Columns' and no extension method 'Columns' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

'object' does not contain a definition for 'Columns' and no extension method 'Columns' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
'object' does not contain a definition for 'SubItems' and no extension method 'SubItems' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

The best overloaded method match for 'System.Collections.Generic.List<System.Windows.Forms.ListViewItem>.Add(System.Windows.Forms.ListViewItem)' has some invalid arguments
Argument '1': cannot convert from 'object' to 'System.Windows.Forms.ListViewItem'

It probably because its a heavily typed language?

Also MSLV is a custom Listview. and the T parameter is and inherited ListviewItem class I ant to use.

can anybody help?
 
C# is a strongly typed language (like VB with option strict turned on) and as such will verify the existence of methods etc. on your variables at compile time.

In the code you have a couple of variables (MSLV and mobj) that are declared as object - this means the existence of methods / properties such as Columns, Text etc. cannot be done by the compiler - you would need to either strongly type the variables or cast them to the correct type before using them.

One thing you could do is to change the method definition to strongly type the MSLV parameter e.g.
C#:
public List<ListViewItem> GetRecords(ListView MSLV, string Query, Type T)
this should remove several errors to begin with.

If the parameter T just defines which type of listviewitem you are using then you could move this to the generic declaration part as well and this would allow you to use more strongly typed code as well.
C#:
 public List<ListViewItem> GetRecords<LVI>(ListView MSLV, string Query) where LVI : ListViewItem, new()
        {
            if (mSqlCeConnection.State == System.Data.ConnectionState.Open)
            {
                PropertyInfo mProperty;
                List<ListViewItem> mList = new List<ListViewItem>();
                SqlCeDataAdapter DA = new SqlCeDataAdapter(Query, mSqlCeConnection);
                DataSet DS = new DataSet("Blank");

                DA.Fill(DS, "Blank");

                foreach (DataTable table in DS.Tables)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        LVI mobj = new LVI();

                        // If the first column is the same as the for column in the row set the text.
                        if (MSLV.Columns[0].Text == table.Columns[0].ColumnName)
                        {
                            mobj.Text =(string) row[table.Columns[0].ColumnName];
                        }

                        foreach (ColumnHeader LVColumn in MSLV.Columns)
                        {
                            // Skip the first column as this is the items column not the sub  items column.

                            if (MSLV.Columns[0].Text != LVColumn.Text)
                            {
                                // Make sure the column is in the row columns list or it will fail.
                                if (row.Table.Columns.Contains(LVColumn.Text) == true)
                                {
                                    mobj.SubItems.Add((string) row[LVColumn.Text]);
                                }
                            }
                        }

                        foreach (DataColumn column in table.Columns)
                        {
                            Type T = mobj.GetType();
                            mProperty = T.GetProperty(column.ColumnName);

                            if (mProperty != null)
                            {
                                mProperty.SetValue(mobj, row[column.ColumnName], null);
                            }
                        }

                        mList.Add(mobj);
                    }
                }

                return mList;
            }
            return null;
        }
The only thing I was unsure of is the loop towards the end where you are looping over the DataColumns - the code above should mimic your original code however.
 
Back
Top