The first one using IEnumerable Single method and it has a InvalidOperationException.
RowObjectType = rowObjectAssemblyTypes.Single(type => type.Name == rowObjectTypeName);
I think the second one does the same thing as the first one and it works fine.
foreach (var type in rowObjectAssemblyTypes)
{
if (type.Name == rowObjectTypeName)
{
RowObjectType = type;
}
}
I'm using .Net3.5. Can anyone tell me the difference between them?
The first one probably crashes because there are zero items or more than one item. This is likely to be a bug and it is good that Single alerted you to that!
The loop doesn't care. It might never assign to RowObjectType or do it multiple times. That's semantically probably not what you want.
If you expect zero items use SingleOrDefault.
Well, technically seen these two do not work the same way.
RowObjectType = rowObjectAssemblyTypes.Single(type => type.Name == rowObjectTypeName);
Will return the only element in the enumerable. If there are either more than one or no elements, this method will throw an exception. A more solid way would be to use SingleOrDefault() and check for null.
The second;
foreach (var type in rowObjectAssemblyTypes)
{
if (type.Name == rowObjectTypeName)
{
RowObjectType = type;
}
}
Will always assign the last element of rowObjectAssemblyTypes which satisfies the if-statement to RowObjectType. If there is only one, it will be assigned properly. However, if there are more, the last object in the enumerable will be assigned.
If you only want the first one, consider;
foreach (var type in rowObjectAssemblyTypes)
{
if (type.Name == rowObjectTypeName)
{
RowObjectType = type;
break;
}
}
Or, even better;
RowObjectType = rowObjectAssemblyTypes.FirstOrDefault(type => type.Name == rowObjectTypeName);
Single(...) requires that exactly one item satisfies the condition.
It will throw an exception if more than one item satisfies the condition.
https://msdn.microsoft.com/en-us/library/vstudio/bb535118%28v=vs.100%29.aspx
Perhaps you need First(...)
.single returns the only element of a sequence where type.Name == rowObjectTypeName, and throws an exception if there is not exactly one element in the sequence
While your second loop is assigning if applicable to more than one or none
The first one is using Linq to return a single object from the list, if there are more than one object which has the same name as rowObjectTypeName then it will throw an exception.
The second one does allows for multiple objects to contain the same name as rowObjectTypeName. However, the final result will be the last match.
Related
This seems to be ridiculously easy, but I just can't seem to find a way to do it. Basically the title, I want to find the first item in my list that meets a requirement, and modify the value of that found item, and if none of the items in that list meets it, then do something else.
I was using a foreach loop to this, but it is definitely not the fastest way.
foreach (CustomClass foo in bar)
{
if (!foo.Value)
{
foo.Value = true;
currentCount++;
break;
}
}
I then tried to use List.First() and catching the exception when it can't find the value, but that is far slower, and I'm looking for performance.
EDIT: Never mind about what is below, I found how to make first or default work, but is there a faster way to do this multiple times than the foreach method? Thanks
So I tried FirstOrDefault, but I keep getting null reference exception
if (bar.FirstOrDefault(c => c.Value == false).Equals(null))
{
break;
}
else
{
thePicture.FirstOrDefault(c => c.Value == false).Value = true;
currentCount++;
}
Anyone know how to make the first or default work? Or is there any other way to do this faster than the foreach method. (This will be ran in another loop a lot of times) Thanks!
FirstOrDefault will return a null reference if no element is found - assuming the element type is a reference type. Instead of calling Equals on the result, just use ==... and don't call it twice:
var first = bar.FirstOrDefault(c => !c.Value);
if (first == null)
{
...
}
else
{
// Use first, I suspect.
// (You don't in the sample code, but...)
}
Note that this won't be faster than an appropriate foreach loop, but it can be more readable.
(bar!=null)?((bar[1].value == true)?(do something):(do something)):do something)
Here you are only checking the first element in list right?
So why going for a loop.
I have a HashSet of generic type UserControl, which can have various UserControl (login, settings). I want to check whether the set contains object of any particular type (say login). If so i want to get that element.
I know its quite easy to do with a loop, but is there any better way?
Unfortunately, you cannot do it without a loop, because you need to try all elements of your collection to check their types. In fact, it does not matter that you have a hash set: it would work the same with a list, or any other enumerable. However, LINQ lets you hide the loop, like this:
var item = hashSet.OfType<DesiredType>().FirstOrDefault();
As #dasblinkenlight says you can use OfType<T>() LINQ method to hide the loop. His answer also uses FirstOrDefault() method so "contains element?" questions is rephrased to "is not null". Another way is to use Count() > 0 after OfType<T>().
var items = hashSet.OfType<DesiredType>();
if (items.Count() > 0) {
DesiredType item = items.First();
...
}
Third way is to put predicate in the FirstOrDefault() method.
var item = hashSet.FirstOrDefault(x =>
x.getType() == typeof(DesiredType)
);
if (item != null) {
...
}
If your set doesn't change that often, you can use GroupBy(func) to reduce computation complexity to O(1). Idea is to build dictionary once and query it instead.
var groups = new Dictionary<Type, IEnumerable<UserControl>>();
foreach(var group in hashSet.GroupBy(x => x.GetType()))
groups.Add(group.Key, group);
.
.
.
if (groups.ContainsKey(typeof(DesiredType)) {
DesiredType item = items.First();
...
}
If I have a collection:
List<T> collection;
and I need to perform two test on this collection, which is more efficient:
foreach(T t in collection.where(w => w.value == true))
{
t.something = true;
}
foreach(T t in collection.where(w => w.value2 == true))
{
t.something2 = true;
}
Or
foreach(T t in collection)
{
if (t.value == true)
{
//check 1
}
if (t.value2 == true)
{
//check 2
}
}
I think it'll be the later because I presume that each where will iterate the collection but just wanted to be sure I wasn't missing something?
I think it might change according the collection size. However I would go with the second code.
The first code iterates the entire collection twice (one per where) and then iterates each result once.
The second code iterates just once the entire collection. Also, it's cleaner.
The second will most likely be slightly faster, but the difference is quite small.
What might be more important is that you do things in a different order. The first code loops through all items acting on one condition first, then again acting on the other condition. The second code loops through the items once, checking both conditions for each item in turn. Depending on what you are doing with the items, that may make a difference.
First case enumerates your collection twice (using WhereEnumerator to do the check for you), the second only once, but you have to do your check manually. The latter case would be more efficient also because you use simple conditional expression to compare the item value, while the WhereEnumerator has to call the supplied delegate on each item.
I'm trying to get a row from my SQL Server database. I don't know how to get it I tried many ways but I coludn't get any good solution.
databasEntities db = new databasEntities();
var medlem = from medlemar in db.medlemar
where medlemar.namn == "Ali"
select medlemar;
Here is my database table Medlemar:
id
namn
losen
epost
medlem will be a collection of objects so you should be able to use foreach or .first on that.
foreach(var m in medlem)
{
var namn = m.namm;
...
}
or
var m1 = medlem.First();
In C#, var is not a typeless type. It is actually a way of implicitly typing objects without having to type out the entire type name.
For example:
var someString = "Any String Value";
and
string someString = "Any String Value";
compile to exactly the same IL.
So in your case, the LINQ is returning an IEnumerable<T> collection, where T is the type of your medlemar object.
Since it is a collection, you need to access it just as you would any other collection. One possibility is using foreach
foreach(var m in medlem)
{
//Do Something
}
Another possibility is calling ToList() and then accessing individual members by index:
var medlemList = medlem.ToList();
var namn = medlemList[i].namn; // where i is some specific index in the collection
Or if you just want to get the first object in the collection, you have several alternatives depending on your use case:
var firstMedlem = medlem.Single();
var firstMedlem = medlem.First();
var firstMedlem = medlem.SingleOrDefault();
var firstMedlem = medlem.FirstOrDefault();
Each of the above do roughly the same thing but will behave differently if the collection has zero or multiple objects.
Single() will return the only object in a collection. If the collection contains multiple objects or zero, an exception will be thrown. Similarly, SingleOrDefault() will throw an exception if there are multiple objects, but will return the value returned by default(T) (usually null, except for when T is a value type).
First() and FirstOrDefault() also behave the same way where First() will throw an exception if the collection is empty and FirstOrDefault() will return the default value. They are different from the Single..() methods in that they will always return the first member if a collection has multiple values.
So basically, FirstOrDefault() will never throw an exception unless the collection itself is null. The other variations will throw an exception in one or more cases depending on the contents of the IEnumerable<T> collection.
I think you need to use FirstOrDefault() something like:
var medlem = from medlemar in db.medlemar
where medlemar.namn == "Ali"
select medlemar;
string nameFromVar = medlem.FirstOrDefault();
There are other options you can use besides FirstOrDefault():
Single returns a single item like FirstOrDefault() but it will throw an exception if there is either none or more than one item.
First also returns a single item, but throw when there is no item.
But in case of the FirstOrDefault() it will return the first item or return null when there is no item or more accurate:
default(TSource) if source is empty; otherwise, the first element in
source.
I often come across code like the following:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
Basically, the if condition ensures that foreach block will execute only if items is not null. I'm wondering if the if condition is really needed, or foreach will handle the case if items == null.
I mean, can I simply write
foreach(T item in items)
{
//...
}
without worrying about whether items is null or not? Is the if condition superfluous? Or this depends on the type of items or maybe on T as well?
You still need to check if (items != null) otherwise you will get NullReferenceException. However you can do something like this:
List<string> items = null;
foreach (var item in items ?? new List<string>())
{
item.Dump();
}
but you might check performance of it. So I still prefer having if (items != null) first.
Based on Eric's Lippert suggestion I changed code to:
List<string> items = null;
foreach (var item in items ?? Enumerable.Empty<string>())
{
item.Dump();
}
Using C# 6 you could use the new null conditional operator together with List<T>.ForEach(Action<T>) (or your own IEnumerable<T>.ForEach extension method).
List<string> items = null;
items?.ForEach(item =>
{
// ...
});
The real takeaway here should be a sequence should almost never be null in the first place. Simply make it an invariant in all of your programs that if you have a sequence, it is never null. It is always initialized to be the empty sequence or some other genuine sequence.
If a sequence is never null then obviously you don't need to check it.
Actually there is a feature request on that here: https://github.com/dotnet/csharplang/discussions/1081#issuecomment-443209795
And the response is quite logical:
I think that most foreach loops are
written with the intent of iterating a
non-null collection. If you try
iterating through null you should get
your exception, so that you can fix
your code.
You could always test it out with a null list... but this is what I found on the msdn website
foreach-statement:
foreach ( type identifier in expression ) embedded-statement
If expression has the value null, a System.NullReferenceException is thrown.
You can encapsulate the null check in an extension method and use a lambda:
public static class EnumerableExtensions {
public static void ForEach<T>(this IEnumerable<T> self, Action<T> action) {
if (self != null) {
foreach (var element in self) {
action(element);
}
}
}
}
The code becomes:
items.ForEach(item => {
...
});
If can be even more concise if you want to just call a method that takes an item and returns void:
items.ForEach(MethodThatTakesAnItem);
It is not superflous. At runtime items will be casted to an IEnumerable and its GetEnumerator method will be called. That will cause a dereferencing of items that will fail
You do need this. You'll get an exception when foreach accesses the container to set up the iteration otherwise.
Under the covers, foreach uses an interface implemented on the collection class to perform the iteration. The generic equivalent interface is here.
The foreach statement of the C#
language (for each in Visual Basic)
hides the complexity of the
enumerators. Therefore, using foreach
is recommended instead of directly
manipulating the enumerator.
The test is necessary, because if the collection is null, foreach will throw a NullReferenceException. It's actually quite simple to try it out.
List<string> items = null;
foreach(var item in items)
{
Console.WriteLine(item);
}
the second will throw a NullReferenceException with the message Object reference not set to an instance of an object.
As mentioned here you need to check is it not null.
Do not use an expression that evaluates to null.
The accepted answer is getting old.
Nowadays, nullable types are used extensively and help the compiler understand what you're trying to achive (and avoid mistakes).
Which means that your list could be this :
List<Item>? list
...OR... this :
List<Item> list
You'll need to check for nullability only for the former case.
Same thing goes for items:
List<Item?> list
...OR... this :
List<Item> list
You'll need to check for nullability of items only for the former case.
And of course finally you have this :
List<Item?>? list
where anything (list and items) could potentially be null.
==================
EDIT: A picture is better than 1,000 words
In C# 6 you can write sth like this:
// some string from file or UI, i.e.:
// a) string s = "Hello, World!";
// b) string s = "";
// ...
var items = s?.Split(new char[] { ',', '!', ' ' }) ?? Enumerable.Empty<string>();
foreach (var item in items)
{
//..
}
It's basically Vlad Bezden's solution but using the ?? expression to always generate an array that is not null and therefore survives the foreach rather than having this check inside the foreach bracket.