Async Action Filter in MVC 4

Why can't I do foreach (var Item in DataTable.Rows)?

Rows effectively returns IEnumerable (DataRowCollection), so the compiler can only pick object as the type for var. Use Rows.Cast<DataRow> if you want to use var.

Cast is defined on Enumerable, so you have to include System.Linq.

Why can't C# infer the type of a DataTable Row

Why can't C# infer the type of row as it would if I was trying to iterate over a string[] for example?

TL;DR: DataTable predates generics :(

DataTable.Rows is declared to return DataRowCollection, which derives from InternalDataCollectionBase. That implements the non-generic ICollection interface, which means that the compiler can't infer the type of row beyond just object.

This isn't specific to DataTable - any time you have something that only implements IEnumerable rather than IEnumerable<T> (and doesn't have a more specific GetEnumerator method for the compiler to use), the inferred iteration element type is just object. When you specify an explicit type for the variable in the foreach loop, the compiler silently inserts a cast for you.

I'd keep the change exactly as you've got it, but an alternative would be to use the Cast LINQ method:

foreach (var row in currentTable.Rows.Cast<DataRow>())
{
var valueAtCurrentRow = row[0];
}

How to iterate through a DataTable

DataTable dt = new DataTable();

SqlDataAdapter adapter = new SqlDataAdapter(cmd);

adapter.Fill(dt);

foreach(DataRow row in dt.Rows)
{
TextBox1.Text = row["ImagePath"].ToString();
}

...assumes the connection is open and the command is set up properly. I also didn't check the syntax, but it should give you the idea.

How to 'foreach' a column in a DataTable using C#?

This should work:

DataTable dtTable;

MySQLProcessor.DTTable(mysqlCommand, out dtTable);

// On all tables' rows
foreach (DataRow dtRow in dtTable.Rows)
{
// On all tables' columns
foreach(DataColumn dc in dtTable.Columns)
{
var field1 = dtRow[dc].ToString();
}
}

Use of C# var for implicit typing of System.Data.Datarow

That's because Rows is DataRowCollection, which in turn is IEnumerable and not IEnumerable<DataRow>, which means that type inferred will be object.

When you explicitly state type in foreach, you instruct c# to add cast to each call, which is why it works.

Why is my added datatable rows disappearing from the table as soon as my foreach loop closes?

NewRow() doesn't add the row. You need to do that manually at the bottom of the loop via .Rows.Add(row). You should also probably create the NewRow() per iteration.

    foreach (var item in issuesByClass)
{
var row = summaryTable.NewRow();

// ...

summaryTable.Rows.Add(row);
}

Behavior of var

The property DataTable.Rows uses an older style (non-generic) collection. The actual type is DataRowCollection which defines an enumerator that is non-generic so it returns instances of type object. To address this problem a new extension method was provided in later versions of the framework (3.5+) called DataTable.AsEnumerable that returns a properly-typed enumerator:

DataTable test = new DataTable();
foreach (var r in test.AsEnumerable())
{
r[1].ToString();
}

If you are stuck on an older version of .NET you would have to cast r to DataRow manually.

Updating a row in a datatable during a foreach C#

as an alternative, using a traditional for loop over a foreach would mean not doing any data copying or anything and would likely run though the datatable faster

for(int i=0;i<table.Rows.Count;i++)
{
if (table.Rows[i]["seqlinnum"].ToString() == "0")
{
table.Rows[i]["seqlinnum"]=maxSequenceNumber; maxSequenceNumber++;
}
}

Object type not recognised on foreach loop

As is stated in the other answers, TreeNodeCollection is a collection of object objects. This is because WinForms was a part of the C# language from the beginning (.NET 1.1), and generics weren't added until .NET 2.0. For backwards compatibility reasons, they did not alter the class to also implement IEnumerable<TreeNode>.

As you discovered, the only way to process them is by explicitly typing the objects as TreeNode within your foreach loop. That is because var wasn't added until .NET 3.5.

One other alternative (though more verbose) would be to get the objects of the type that you want:

foreach (var child in nodes.OfType<TreeNode>())

As I said, this is more verbose, and you would be better suited to just explicitly cast the objects. However, the OfType method is a good one to have in your repertoire.

Clarification

As mentioned in comments on Patrick's answer, another option is .Cast<T>(). However, if you do that, exceptions are thrown if an item cannot be cast to the specified type. In a situation like this, you are fine because based on the way that the collection is created, you won't have anything that is not a TreeNode. But, in other collections, it is possible to have other types based on super classes, etc. OfType<T>() will ignore anything that is not of the type you are requesting.

Why does var evaluate to System.Object in foreach (var row in table.Rows)?

That's because the DataRowCollection class only implements the non-generic version of IEnumerable. So the compiler doesn't know what the type of the variable is.

By explicitly putting the type in there, you basically tell the compiler to generate an explicit cast from object to DataRow.

This is a problem you'll find with many of the collections and classes added back in the .NET 1.x days, before generics were available.



Related Topics



Leave a reply



Submit