I want to get value in my object. When I look my inside of object, I can see my value in Result View IEnumerable. But, I can't get this values.
When I write "value."; just see "ToString, GetType, GetHashCode and Equals". I try GetType and get value but I can't. Because, I haven't name of values. How solve we this problem?
The IEnumerable uses syntactic sugar in the background. IEnumerable I feels like a list but behaves differently. The bigest different is that IEnumerable is lazy evaulated. This means only the requested object will be loaded into the memory. The interface hase a CurrentItem property that is accessed by foreach loop.
Here are some options to access the underlaying value:
User foreach
foreach (var value in myEnumerableCollection)
{
Console.WriteLine(value);
}
Use LINQ
var value = myEnumerableCollection.FirstOrDefault(x => x == someSearchTerm);
Cast the enumartion to a list and use the list methods and use indexers or other list methods to grab the value. A small warning, this will force the collection load every element into the memory. If it is large this may cause some issues. For example loading x million rows of db table with no pagination.
int index = 1;
var value = myEnumerableCollection.ToList()[index];
You can cast your value to IEnumerable T, where T - is your type, for example:
if (value is IEnumerable<int> resultList)
{
foreach (int item in resultList)
{
Console.WriteLine(item);
}
};
Related
so far I have done this:
List<string[]> VList
foreach (var item in VList)
{
foreach (var b in item)
{
Richtextbox 1 = VList[item][b]?
}
}
How do I do this correct? I want it to write everything that the list contains
A foreach loop iterates a collection1 using an IEnumerator1.
In each iteration, the loop variable (item and b in your case) references whatever the IEnumerator.Current property is referencing.
The square brackets [] are used for a special kind of property called indexers. Indexers are typically used in a collection2 to provide a reference to whatever the collection is holding that is coupled to that specific index.
When you are using a foreach loop, you don't need to know the index of an element in the collection - and in fact, the collection doesn't even have to support indexes - you already have a reference to it via the loop variable.
So a code that uses a nested foreach loop to do something with the strings inside a variable of type List<string[]> would be something like this:
foreach(var stringArray in VList)
{
foreach(var str in stringArray)
{
// do something with str here...
}
}
If you want to use indexers, use a for loop instead:
for(var i=0; i<VList.Count; i++)
{
for(var j=0; j<VList[i].Length; j++)
{
// do something with VList[i][j] here...
}
}
1 Actually, a foreach loop doesn't need an actual collection to work with.
It only needs an instance that has a method called GetEnumerator() that returns an object that has a public property called Current and a public method called MoveNext.
This means that even if you have a class that doesn't implement the IEnumerable interface but has the GetEumerator method, and that method returns an instance of some other class that doesn't implement the IEnumerable interface but has the Current property and the MoveNext method, you can still use foreach with that. This is called duck typing.
This is documented in foreach, in (C# reference)
2 The fact that a type has indexer doesn't have to mean that the type is a collection - it's perfectly valid to add indexres to your own type without implementing any interface collections usually implement such as IEnumerable or ICollection.
Your access is wrong. You are iterating over the elements there is no need to use the array/indexer access. []
List<string[]> VList
foreach (var item in VList)
{
foreach (var b in item)
{
Richtextbox1.text += b
}
}
Let's say I have a list of employee instances, employeeList. I can iterate through them, like this:
IEnumerator enumerator = employeeList.GetEnumerator();
while (enumerator.MoveNext())
{
Console.Write(enumerator.Current + " ");
}
I have three questions:
I have a general idea about how enumerators work, just like iterators in C++. But I don't understand the MoveNext() method (like itr ++ in C++), because the method first checks the condition (whether it is in the last element). Let's say we use enumerator.Current to access the first element: I think it actually has already "moved" to the next element in the list, as MoveNext() has been called. So shouldn't the object that Current points to actually be the second element in the list?
I think it would make sense that we can access the current element when using enumerator.Current. For example, we should be able to use enumerator.Current.name, just like we can use (*itr).name or itr=>name in C++. However, C# looks like it doesn't implement this kind of functionality. So what's the point of using enumerator.Current?
This question is not related to IEnumerator. I just saw some code like this:
IEnumerable<int> result = GetData() ?? Enumerable.Empty<int>;
As a beginner in C#, I only know the && and || operators. What is ???
Read documentation: "After an enumerator is created, the enumerator is positioned before the first element in the collection, and the first call to MoveNext advances the enumerator to the first element of the collection"
The problem with your code is that you assign the enumerator to a non-generic enumerator variable. That works because the generic IEnumerator<T> interface inherits from the non-generic. But that's also the reason why you can't use properties of the Employee-class since the type is Object. You have to cast enumerator.Current to the correct type first.
Therefore it's better to use the generic version (and dipose it properly with using):
using(IEnumerator<Employee> empEnumerator = employeeList.GetEnumerator())
{
while(empEnumerator.MoveNext())
{
// now empEnumerator.Current is the Employee instance without casting
Employee emp = empEnumerator.Current;
string empName = emp.Name; // ...
}
}
You can also use var which works like a placeholder for the real type in C#:
using(var empEnumerator = employeeList.GetEnumerator())
{ ... }
If all you need is to enumerate the whole collection a foreach is more comfortable:
foreach(Employee emp in employeeList)
{
Console.WriteLine(emp.Name);
}
Initially, the enumerator is positioned before the first element (since an enumerable might be empty). Thus, the first invocation of MoveNext moves it to the first element (or returns false, if the enumerable is empty).
You are using the old, non-generic version of IEnumerator, where Current returns an object. You can cast the object to the concrete type and invoke .name, or, even better, use a type for employeeList which returns a strongly typed IEnumerator<Employee> (such as List<Employee>).
This is the null-coalescing operator.
PS: In the future, please create one SO question per question. 1+2 can be seen as related, but 3 definitely isn't.
PPS: If you just want a space-separated list of employee names, you don't need an explicit loop at all:
var names = String.Join(" ", employeeList.Select(e => e.name));
Use IEnumerable just this way:
foreach (var e in employeeList)
{
Console.Write(e + " ");
}
IEnumerable Interface
Exposes an enumerator, which supports a simple iteration over a non-generic collection.
foreach (var employee in employeeList)
{
// do your stuff here, you have full employee object
Console.WriteLine(employee.FirstName);
}
c# null coalescing operator
The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.
I am using ArrayList in Asp.net I want to extract specific items . My code is
ArrayList items = (ArrayList)Session["mycart"];
foreach(var v in items)
{
}
but this is not working . I want to get value like
v.myvalue;
My arralist is filled with several items coming from prevoius page.
The issue is that ArrayList stores all elements as object. You need to perform a cast to the type of object that contains myvalue.
For example
ArrayList items = (ArrayList)Session["mycart"];
foreach(var v in items)
{
MyObject o = v as MyObject;
if (o != null)
{
// do stuff with o.myvalue
}
}
It may be better to just use the generic List class rather ArrayList, although you may have a perfectly reason for doing otherwise. Generally, you should use the generic (e.g. List<MyObject>), not only for performance but also ease of use.
A ListBox control has an Items property of type ListItemCollection.
I sort of understand why I can't write
foreach (var item in ShipperListBox.Items)
{
if (item.Selected) count++;
}
But instead have to write
foreach (ListItem item in ShipperListBox.Items)
{
if (item.Selected) count++;
}
It has to do with ListItemCollection implementing IEnumerable and not IEnumerable<ListItem> (as explained in this question).
But what I don't get is why the following is no problem.
for (int i = 0; i < ListBox1.Items.Count; i++)
{
if (ListBox1.Items[i].Selected) count++;
}
What part of ListItemCollection is making it clear to the compiler that ListBox.Items[i] is of type ListItem?
Because ListItemCollection implements an indexer that returns a ListItem.
This is separate from IEnumerable.
This is part of what .OfType<ListItem>() and .Cast<ListItem>() explicitly exist for:
The Cast(IEnumerable) method enables the standard query operators to be invoked on non-generic collections by supplying the necessary type information. For example, ArrayList does not implement IEnumerable, but by calling Cast(IEnumerable) on the ArrayList object, the standard query operators can then be used to query the sequence. (source)
So you can write
foreach (var item in ShipperListBox.Items.OfType<ListItem>())
{
if (item.Selected) count++;
}
I couldn't tell you why, though.
ListItemCollection.GetEnumerator does return an enumerator which was used since .NET 1.0 which does return object as value. The foreach pattern (as Eric Lippert does explain in much greater detail) requires an Enumerator returned by the object via the GetEnumerator method.
When you use var the compiler infers the type of you loop variable as object since Current of the Enumerator does return only an object.
public interface IEnumerator
{
bool MoveNext();
object Current { get; }
void Reset();
}
But when you use foreach(ListItem item in xxx) ... the compiler does add a cast to ListItem from object automatically for you. You can try it out when you do a foreach(string str in new object[] { "str", 1 }) which will result in an InvalidCastException. There is no magic going with the var keyword. It simply does infer the type without doing any extra magic.
When you expect a ListItem in your loop you should write it out clearly. From the method signature of the enumerator it is not clear what objects it will return. You have to tell the compiler which types you expect. One more reason to not use the var keyword since the readers of your code will also not be able to deduce the type of your looping variable as well.
I'm working on some code which uses dynamic variables.
dynamic variable;
Behind scenes, this variable contains collection of Shapes which is again collection of dynamic variables.
So code like this working fine:
foreach(var shape in variable.Shapes) //Shapes is dynamic type too
{
double height = shape.Height;
}
I need to get first item height from this collection.
This hack works well:
double height = 0;
foreach(var shape in variable.Shapes)
{
height = shape.Height; //shape is dynamic type too
break;
}
Is there better way to accomplish this?
Because variable is dynamic, you won't be able to evaluate variable.Shapes.First(), since determination of extension methods occurs at compile time, and dynamic invocation occurs at runtime. You will have to call the static method explicitly,
System.Linq.Enumerable.First<TType>(variable.Shapes).Height.
Where TType is the expected type of the items in the enumerable.
Otherwise, use LINQ as others have suggested.
Description
You can use the LINQ method First() or FirstOrDefault()to get the first item.
First() - Returns the first element of a sequence.
FirstOrDefault() - Returns the first element of a sequence, or a default value if the sequence contains no elements.
Sample
using System.Linq;
double height = 0;
// this will throw a exception if your list is empty
var item = System.Linq.Enumerable.First(variable.Shapes);
height = item.Height;
// in case your list is empty, the item is null and no exception will be thrown
var item = System.Linq.Enumerable.FirstOrDefault(variable.Shapes);
if (item != null)
{
height = item.Height;
}
More Information
MSDN - LINQ (Language-Integrated Query)
MSDN - Enumerable.First Method
MSDN - Enumerable.FirstOrDefault Method