Convert Short? to System.Collection.Generic.List - c#

I have a variable called filter being passed into the SaleList from the view. When it first loads its always NULL which is should be. I seem to be having an issue with the else statement k = filter. I have tried a couple things which no such luck. Any help would be appreciated .
Cannot implicitly convert type short?[]' to System.Collection.Generic.List
I am not sure how convert this
short? filter = sale.SalesStatusID;
List<short> k;
if (filter == null)
{
k = (from s in _db.SalesStatus
select s.SaleStatusID).ToList();
}
else
{
k = filter;
}
var sales = from t in _db.Sales
where k.Contains((short) t.SalesStatusID)
select t;

The variable k is a collection of short and your filter variable is a nullable short. You cannot assign a nullable short(singlet item) to a collection type.
You can create a collection using your filter variable value and assign it.
List<short> k;
if (filter != null)
{
k = new List<short> { filter.Value };
}
else
{
k = new List<short>();
}
Or even better, initialize the empty list and add to it.
List<short> k = new List<short>();
if (filter != null)
{
k.Add(filter.Value);
}
But, Keep in mind that (short) t.SalesStatusID will give you unexpected results. What if you SalesStatusID value is a number which is bigger than short.MaxValue(32767) ? So i suggest use the same type and avoiding the casting.
List<int> k = new List<int>(); //Assuming SalesStatusID's type is int32
if (filter != null)
{
k.Add(filter.Value);
}
else
{
k = _db.SalesStatus.Select(a=>a.SaleStatusID).ToList();
}
// use k now

You're assigning k (which is a List type) to value of filter (which is nullable short type) You need to change your else statement to this
else
{
k.Add(filter.Value);
}

Related

How to store multiple datatype values into single list without defining class?

Expected result :
List<something> obj = new List<something>(); //something is i need.
string[] val = new string[] {"hi","20"}; //here I used static but input data fetch from CSV file. So we don't know when which type of data will come?.
int intval;
for(int i=0;i<val.Length;i++)
{
if(int.TryParse(val[i],out intval)
{
obj.add(intval); //here I face the error "Cannot implicitly convert int to string"
}
else
{
obj.add(val[i]);
}
}
I need to add int value and also string value into the same list. But The condition is Developer don't know when which type of value will come. So here I used TryParse to convert values and store into list.
How to declare a list or any other methods are there?
Note: Don't use Class to declare field and define like List<classname> val = new List<classname>();
Not sure why you want to do this but I think the code below is what you're looking for. I suppose you can later check if each list value typeof is string/int but why store multi value types in one list like this?
string[] val = new string[] { "hi", "20" };
List<object> objs = val.Select(x =>
{
if (int.TryParse(x, out var intval))
return (object)intval;
else
return (object)x;
}).ToList();
If you just need to store all the results that you get to a single list without caring about the type then dont Parse to int type like
for (int i = 0; i < val.Length; i++)
{
//simply add the
obj.add(val[i]);
}
Just use a List<object>. Every type ultimately derives from object:
List<object> obj = new List<object>();
string[] val = new string[] {"hi","20"};
for(int i = 0; i < val.Length; i++)
{
if(int.TryParse(val[i], out var intval)
{
obj.add(intval);
}
else
{
obj.add(val[i]);
}
}

.Net dynamic list conversion

I have to do a comparison of 2 lists. The problem is that I don't know of what type the field inside the list are, they can be int, string, decimal, enums or even other objects.
I will know the type only on runtime. I was thinking of creating a list of object and cast them to object the problem is that let's say I have a List<int> and I'm trying to cast it to object it fails.
Another problem is that I know there is a list only on runtime. so on runtime I need to transform the variable of type object to a list.
How can I cast that object to List and how can I cast it to let's say list of objects?
Update:
I have and object and by reflection I'm getting the the property of it with
var oldProperty = property.GetValue(old);
var newProperty = property.GetValue(new);
Once I have the properties values and I can see it's a list I will need to compare those 2. Let's say oldProperty is of type List
I've tried to do something like:
var myOldList = (List<object>)oldProperty;
If the cast fails with
Unable to cast object of type 'System.Collections.Generic.List`1[System.Int32]' to type 'System.Collections.Generic.List`1[System.Object]'
Here you have a look of the function i;m trying to create. Please don't mind of null objects(is not in the scope)
public void SetDifference(object first, object second)
{
var properties = first.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
var oldValue = property.GetValue(first);
var newValue = property.GetValue(second);
if (Convert.GetTypeCode(newValue) != TypeCode.Object)
{
if (!oldValue.Equals(newValue))
{
result.AddDifference(new PrimitiveComparison()
{
BeforeValue = oldValue.ToString(),
AfterValue = newValue.ToString(),
PropertyName = property.Name
});
}
}
else
{
if (property.PropertyType.Name.Contains("List"))
{
// here fails with the error from above
var oldList = (List<object>)oldValue;
var newList = (List<object>)newValue;
if (oldList.Count != newList.Count)
{
result.AddDifference(new PrimitiveComparison()
{
BeforeValue = oldList.Count.ToString(),
AfterValue = newList.Count.ToString(),
PropertyName = property.Name + "Count"
});
}
// add the list differences
result.AddDifference(SetListDifference(oldList, newList);
}
else
{
var diffrence = SetDifference(oldValue, newValue);
if (!diffrence.areEqual)
{
result.AddDifference(diffrence);
}
}
}
}
}
You can just cast your two values to IList and compare them, for example like this:
static bool AreEqual(IList first, IList second) {
if (first.Count != second.Count)
return false;
for (int i = 0; i < first.Count; i++) {
if (!object.Equals(first[i], second[i]))
return false;
}
return true;
}
once you do conversion of you list than you can check both the list have same element or not by using except method of linq, to find both are equal or not
double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
double[] numbers2 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);
if(onlyInFirstSet.Count() ==0)
Console.WriteLine("equal");
for primitive type this works fine but for user defined type you need compare implementation.
Check this blog post for comparing list of two different type : Difference between list of user defined types
If you are aware that is going to be IEnumerable type than you can try
List<object> objlst = (value as IEnumerable<object>).Cast<object>
().ToList()
you can try like this
Type t = typeof(obj);
if (t == typeof(List<int>)) {
var lst= (List<int>)obj;
} else if (t == typeof(List<string>)) {
var lst = (List<string>)obj;
} else if (t == typeof(List<decimal>)) {
var lst = (List<decimal>)obj;
}
else if (t == typeof(List<EnumName>)) {
var lst = (List<EnumName>)obj;
}

How do you remove trailing objects from a list with linq?

I have a collection of objects with properties and I want to remove all the trailing objects with (say) a value of 0 in LINQ.
public class Object
{
public Object(){}
public int Property {get; set;}
}
and if I have a list of objects:
new Object(){ Property = 1};
new Object(){ Property = 0};
new Object(){ Property = 9};
new Object(){ Property = 7};
new Object(){ Property = 0}; // "trailing zero"
new Object(){ Property = 0}; // "trailing zero"
new Object(){ Property = 0}; // "trailing zero"
How would I go about removing the "trailing zeros" in this list? I don't want to remove all properties with a zero, but I want to remove any objects from the list with a property value of zero if it it is not later followed by a property value of something greater.
Standard solution for sequences of finite size - reverse, remove from start, reverse:
var withoutTail = sequence
.Reverse()
.SkipWhile( x => x == 0) // whatever condition you need
.Reverse();
This is very non-optimal, so if you actually have real collection (i.e. List) it would be better to just remove items starting from last index.
Write an extension method:
static class Extensions
{
public static IEnumerable<T> TrimTrailing<T>(this IEnumerable<T> items,
Predicate<T> test)
{
if (items == null) throw new ArgumentNullException(nameof(items));
if (test == null) throw new ArgumentNullException(nameof(test));
var buf = new List<T>();
foreach (T item in items)
{
if (test(item))
{
buf.Add(item);
}
else
{
foreach (T bufferedItem in buf)
{
yield return bufferedItem;
}
buf.Clear();
yield return item;
}
}
}
}
Then, if you have an IEnumerable<Object> called l, you would call TrimTrailing using
var trimmed = l.TrimTrailing(o => o.Property == 0);
Be careful with this, though: in the worst case, it buffers all the items from items and then throws away the buffer.
Just iterate your list backwards removing any 0 entries and stop either at the beginning of the list or the Property != 0.
for (int i = list.Count - 1; i >= 0; i--)
{
var item = list[i];
if (item.Property == 0)
{
list.RemoveAt(i);
}
else
{
break;
}
}
This will allow for a single pass through your list.
You can use FindLastIndex to find the last non-0 index, and Take the elements up to that.
var result = list.Take(list.FindLastIndex(x => x.Property != 0) + 1);

c# Reflection Generic List Count

Is there a cleaner way to get a list count using reflection then this?
Boolean include = false;
foreach (PropertyInfo item in props)
{
var pt = item.PropertyType;
String listType = pt.GetGenericArguments()[0].Name;
// Is there a better solution than this?
switch (listType)
{
case "jsonResult":
var list = v as List<jsonResult>;
include = list.count > 0;
break;
}
}
)
I've tried a variety of ideas from Googling but haven't had any luck.
I didn't completely understand what is the "v" variable, but if it is an object and when it's a collection you want to get its count, you can do that this way:
var count = GetCount(v);
if (!count.HasValue)
continue; // Or any other code here
include = count.Value > 0;
The "GetCount" method:
private static int? GetCount(object #object)
{
var collection = #object as System.Collections.ICollection;
if (collection == null)
return null;
return collection.Count;
}

nullable var using implicit typing in c#?

Is there anyway to have the var be of a nullable type?
This implicitly types i as an int, but what if I want a nullable int?
var i = 0;
Why not support this:
var? i = 0;
var is typed implicitly by the expression or constant on the right hand side of the assignment. var in and of itself is not a type so Nullable<var> is not possible.
Why support it? If that's what you mean, you should say var i = (int?)0; instead.
(Well, you should probably just say int? i = 0, but for more complicated types, etc.)
The problem deals with nullable types.
For instance, you cannot create a nullable string, which in turn prevents you from creating a nullable var, since var could be a string.
My answer is kind of along these lines. "var" is implicitly typed. It figures out what type it is by the value supplied on the right-hand side of the assignment. If you tell it that it's nullable it has no idea what type to be. Remember, once it's assigned, that's the type it's going to be forever.
Try this - is this what you're talking about?
static void Main(string[] args)
{
for (int i=0; i < 10; i++)
{
var j = testMethod();
if (j == null)
{
System.Diagnostics.Debug.WriteLine("j is null");
}
else
{
System.Diagnostics.Debug.WriteLine(j.GetType().ToString());
}
}
}
static int? testMethod()
{
int rem;
Math.DivRem(Convert.ToInt32(DateTime.Now.Millisecond), 2, out rem);
if (rem > 0)
{
return rem;
}
else
{
return null;
}
}
VAR is an implicit type determined by the compiler at the time of compilation. It is assigned upon first use. IE when you set var I = 1, var is an int because that is what the number 1 is. If you instead have var I = SomeFunction() where some function returns a nullable int than I will be set as int?. Now with that said var should not be used in a case where you want to control what the variable type is.
So bottom line, as per your example using var is wrong and should be explicitly set to int? from the start.
Darroll
I wouldn't even use var in this case. If it's a complex type or a simple one such as an int I would use type "object".
Example:
//Define all global class variables
List<int> m_lInts = New List<int>();
List<string> m_lStrs = New List<string>();
public static object FindMyObject(string sSearchCritera)
{
//Initialize the variable
object result = null;
if (result == null)
{
//Search the ints list
foreach(int i in m_lInts)
{
if (i.ToString() == sSearchCritera)
{
//Give it a value
result = (int)i;
}
}
}
if (result == null)
{
//Search the ints list
foreach(string s in m_lStrs)
{
if (s == sSearchCritera)
{
//Give it a value
result = (string)s;
}
}
}
//Return the results
return result;
}

Categories