Would this LINQ statement ever return null? - c#

Given the following C# code:
List<string> source = new List<string>();
IEnumerable<string> values = from value in source select value;
Will values ever be null or will it always return an empty sequence?

Yes it CAN return null if you have an extension method defined in your code somewhere like the following:
public static IEnumerable<string> Select(this List<string> list, Func<string, string> action)
{
return null;
}
Otherwise no; it will return an empty sequence.

The values sequence itself will never be null. If source is empty then values will be an empty sequence containing no items.
(And, of course, it's possible that one or more of the string items in the sequence might be null.)

Linq returns empty sequences
If you want to test if the sequence is empty use the .Any() method

Related

Except a generic list with another generic list without applying distinct operation

In the following code, I expect the result has 2 elements with same values("Item1","Item1") but the result has 1 element("Item1"):
var list = new List<string>(){"Item1","Item1"};
var emptyList = new List<string>();
// I expect the result of follwing line be {"Item1","Item1"} but is {"Item1"}
var result = list.Except(emptyList);
Seems Except() method return unique values of the result set, How can I get desired value?
The definition itself has set.
Produces the set difference of two sequences.
If you read the documentation carefully.
The set difference between two sets is defined as the members of the first
set that don't appear in the second set.
This method returns those elements in first that don't appear in
second. It doesn't return those elements in second that don't appear
in first. Only unique elements are returned.
Workaround is to use list.Where(x => !emptyList.Contains(x))
Also, refer to this question for more clarity.
You could use the following:
var result = list.Where(s => !emptyList.Contains(s));
Performance will be worse but whether that matters depends on your dataset.
Just mock the ExceptIterator, replace Add with Contains
private static IEnumerable<TSource> ExceptOrdinaryIterator<TSource>(
IEnumerable<TSource> first, IEnumerable<TSource> second)
{
var set = new HashSet<TSource>(second);
foreach (TSource element in first)
if (!set.Contains(element))
yield return element;
}

C# - Cant convert var to List

This code snippet returns me an error,
public List<auto> autoSelect()
{
return autoSelect(DateTime.Today);
}
public List<auto> autoSelect(DateTime date)
{
var onderhoudAuto = (from onderhoud in db.onderhouds
where onderhoud.uitvoerdatum != DateTime.Today
select onderhoud)
.FirstOrDefault();
List<string> autos = (from auto in db.autos
where auto.autoId.Equals(onderhoudAuto)
select auto)
.FirstOrDefault();
return autos;
}
I tried convert the var to a list with .ToList(); although this doesn't work. Does anyone have any suggestions?
I tried convert the var to a list
No, you do not. var is not actually a data type - it is resolved by the compiler. A tooltip should show you the real type.
Your problem is different:
Looking at your code, we can see:
The method autoSelect signature states that the return type is List<auto>
public List<auto> autoSelect(DateTime date)
The variable autos type is List<string>
List<string> autos = [...etc...]
return autos;
You return autos, but it is not possible to return a List<string> when a List<auto> is expected.
So it has nothing to do with var - it is simply you selecting as single property and returning a list of strings, but that is not the type the method is supposed to return.
If you use FirstOrDefault() after your linq query, you are saying you want the first element (or the default -usually null- for the datatype if none matches) in the LINQ query, not a list of elements.
If you want a list of elements, use ToList() on the linq query, not try to convert a single entity to a list.
If you, for some reason, want a list of a single entity, then create a list (with new List<type>()) and then add your entity (of the same type as your list) to the list.

Cast IEnumerable<object> to List<object>

I have the following code:
public IList<MyObject> GetSomeData(string inputParam)
{
var temp = repository.GetData(inputParam);
var list = temp as List<MyObject>;
return list;
}
The return value of repository.GetData is IEnumerable<IMyObject>
When I look at the value of temp, it has 400+ records. The moment I cast it to list, it becomes null. Why is this cast not possible?
It returns null because that IEnumerable isn't actually a list. The cast will only succeed if that particularly IEnumerable happens to be a List, instead of some other type of sequence. If you want to have a list, you will need to create a new list and add the items from the sequence into that list.
Unless the underlying object of the value returned from repository.GetData matches what you are trying to cast it to then the result will always be null. Because the generic element types of the method and what is actually return from repository.GetData are different you will need to do some conversions to get the desired result
Assuming that MyObject implements IMyObject I can think of at least to ways using System.Linq to get the result you seek.
Option 1: Cast<T>()
Casts the elements of an System.Collections.IEnumerable to the specified type.
First convert the content of temp using the Cast<MyObject>() linq extension and then use the ToList<T>() extension method to get you resulting IList<MyObject>
public IList<MyObject> GetSomeData(string inputParam)
{
//repository.GetData returns IEnumerable<IMyObject>
var temp = repository.GetData(inputParam);
var list = temp.Cast<MyObject>().ToList();
return list;
}
Option 2: OfType<T>()
Filters the elements of an System.Collections.IEnumerable based on a specified type.
Filter the content of temp using the OfType<MyObject>() linq extension and then use the ToList<MyObject>() extension method to get you resulting IList<MyObject>
public IList<MyObject> GetSomeData(string inputParam)
{
//repository.GetData returns IEnumerable<IMyObject>
var temp = repository.GetData(inputParam);
var list = temp.OfType<MyObject>().ToList();
return list;
}

Is this achievable with a single LINQ query?

Suppose I have a given object of type IEnumerable<string> which is the return value of method SomeMethod(), and which contains no repeated elements. I would like to be able to "zip" the following lines in a single LINQ query:
IEnumerable<string> someList = SomeMethod();
if (someList.Contains(givenString))
{
return (someList.Where(givenString));
}
else
{
return (someList);
}
Edit: I mistakenly used Single instead of First. Corrected now.
I know I can "zip" this by using the ternary operator, but that's just not the point. I would just list to be able to achieve this with a single line. Is that possible?
This will return items with given string or all items if given is not present in the list:
someList.Where(i => i == givenString || !someList.Contains(givenString))
The nature of your desired output requires that you either make two requests for the data, like you are now, or buffer the non-matches to return if no matches are found. The later would be especially useful in cases where actually getting the data is a relatively expensive call (eg: database query or WCF service). The buffering method would look like this:
static IEnumerable<T> AllIfNone<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
//argument checking ignored for sample purposes
var buffer = new List<T>();
bool foundFirst = false;
foreach (var item in source)
{
if (predicate(item))
{
foundFirst = true;
yield return item;
}
else if (!foundFirst)
{
buffer.Add(item);
}
}
if (!foundFirst)
{
foreach (var item in buffer)
{
yield return item;
}
}
}
The laziness of this method is either that of Where or ToList depending on if the collection contains a match or not. If it does, you should get execution similar to Where. If not, you will get roughly the execution of calling ToList (with the overhead of all the failed filter checks) and iterating the result.
What is wrong with the ternary operator?
someList.Any(s => s == givenString) ? someList.Where(s => s == givenString) : someList;
It would be better to do the Where followed by the Any but I can't think of how to one-line that.
var reducedEnumerable = someList.Where(s => s == givenString);
return reducedEnumerable.Any() ? reducedEnumerable : someList;
It is not possible to change the return type on the method, which is what you're asking. The first condition returns a string and the second condition returns a collection of strings.
Just return the IEnumerable<string> collection, and call Single on the return value like this:
string test = ReturnCollectionOfStrings().Single(x => x == "test");

How to replace value in string array

How to remove my value in String Array and how i can rearrange
public string[] selNames = new string[5];
selNames[0]="AA";
selNames[1]="BB";
selNames[2]="CC";
selNames[3]="DD";
selNames[4]="EE";
In certain Conditaion i need to Check for the existing value and i want to remove it from my collection, How i can do it.
i tried like below, but i cannot, it returns true, but how to make that index value to null
If(selNames .Contains("CC").ToString()==true)
{
// how to make that index null which contains the "CC"; and i need to rearrage the array
}
You can do following.
var newArray = selNames.Where(s => s != "CC").ToArray();
where s is the arg of the Func<TSource, bool> delegate TSource is string in your case.
So it will compare each string in array and return all which is not "СС"
here is a link to msdn
You can use the 'List< T >' for checking the existing values and also can remove the item from the list and also can arrange the list.
The following is the code snippet:
List<string> list = new List<string>();
list.Add("AA");
list.Add("BB");
list.Add("CC");
list.Add("DD");
list.Add("EE");
list.Add("FF");
list.Add("GG");
list.Add("HH");
list.Add("II");
MessageBox.Show(list.Count.ToString());
list.Remove("CC");
MessageBox.Show(list.Count.ToString());

Categories