assign Ienumerable parameter to ArrayList - c#

I am trying to pass constructor IEnumerable and assign it to Arraylist
but it gives me that error
cannot convert from 'System.Collections.IEnumerable' to 'int'
Why can you explain me
IList name;
public Class1(IEnumerable list)
{
name = new ArrayList(list)
}

One option is to use:
name = new ArrayList(list.Cast<object>().ToArray());
This is necessary since ArrayList does not have a constructor that takes a IEnumerable but it does have one that takes an ICollection (and arrays implement ICollection).
I'd also strongly suggest you use List<T> rather than ArrayList in future.

You should use linq for this
name = list.ToList()

Related

Cast List<object> to List<string>

I've spent way to much time on trying to resolve this and I don't understand why I can't cast this. I'm executing a query and pulling all the values from a specific column that is then stored in a List since it could be an int, string, or bool. The issue is during casting, I would like a dynamic solution that can validate the object type and cast accordingly.
//This handles the db connection and makes calls DbItems class
public List<object> GetDBColumns(string sqlQuery, string column)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
var reader = new SqlCommand(sqlQuery, connection).ExecuteReader();
var values = DbItems.GetColumns(reader, column);
connection.Close();
return values;
}
}
Public class DbItems
{
DbItems(SqlDataReader reader, string column)
{ //GetInt32 won't be able to handle other types of course, what could I use?
columnData.Add(reader.GetInt32(reader.GetOrdinal(column)));
}
List<object> columnData = new List<object>();
//I'm calling this static method that invokes the constructor
public static List<object> GetColumns(SqlDataReader reader, string column)
{
List<object> dataSet = new List<object>();
while (reader.Read())
{
dataSet.Add(new DbItem(reader, column).columnData);
}
return dataSet;
}
}
This works without issue, but then I'll get an int value that I'd like to cast a string and I've used Cast<>, (string)columnData[0], and a couple other suggestions online and nothing works. Please assist.
Casting List<object> to List<string> would require contravariance of List's generic parameter T. Unfortunatelly List<T> does not meet criteria for contravariance, because it is not an interface, delegate or array type, and because making it's generic parameter contravariant wouldn't be type-safe (doing so would e.g. allowed List<string> to contain not only strings, but any other object, which is obviously nonsence, not type-safe and therefore not allowed). Fot this reason, you cannot cast List<object> to List<string>.
What you can, however, is to create new List<string> and copy there all items from original List<object>, while converting each item to string. Item conversion with Cast<> or (string)columnData[0] will not work here (unless items are actually a strings), because casting a reference-type object to another reference-type only performs assignment compatibility check, but does not perform any conversion of the object.
Luckily, converting to string is trivial, since all objects inherits .ToString() method from Object type. So you can convert to List<string> with the following:
List<string> stringList = columnData.ConvertAll(item => item?.ToString());
But of course, you can use any other conversion, if .ToString() does not meet your needs, such as using Convert class to perform conversion between primitive types.
The easiest way to do so would be just call the ToString Method, since all object have a ToString Method
var values = columnData.Select(x => x?.ToString()).ToList();

Linq namespace and method any()

So I am using System.Linq namespace and method Any() but for some reason it's shows me an error:
ArrayList does not contain a definition for Any...
I am trying to check if an array contains any item from another array. Dont know why but cant post my code. Hope you know what the problem is.
Don't use ArrayList. Use List instead.
Becouse ArrayList doesn't implement IEnumerable<T> generic interface and extension methonds from System.Linq work only with collecions that implement interface IEnumerable<T> like List<T> for example.
ArrayList is a loosely-typed collection (see in reference source) and cannot be used with Enumerable.Any which requires a strongly-typed collection (see in reference source).
BTW, you should not use loosely-typed collections, use generic collections instead.
You shouldn't use non-generic collections.
But If you really want to do this, you can write a helper method for translating your collection to IEnumerable.
static void Main(string[] args)
{
var list = new ArrayList {3, "test", null};
var result = AsEnumerable(list).Any(x => x == null);
}
private static IEnumerable<object> ToEnumerable(ArrayList data)
{
var enumerator = data.GetEnumerator();
while (enumerator.MoveNext())
yield return enumerator.Current;
}
But It's just an example. Use List instead of ArrayList

How to check if an object is a list enum type objects?

I have an object that can be a list of different enum types or non-enum types (normal class instances).
To verify if object is a list is easy:
myobject is IList
Now I can verify the type of list's elements:
(myobject as IList)[0].GetType().IsEnum
But how to verify if my list's elements are enums IF I have no elements yet ?
if (myobject is IList)
{
if ((myobject as IList).Count > 0)
{
if ((myobject as IList)[0].GetType().IsEnum)
return true;
}
else
{
// how to check if the list is enum list here ?
}
}
An IList can contain whatever type it wants, so if you don't have any contents you have no way of checking. If you actually have a generic type to start with you can check by using the GetGenericArguments method of Type. (GetInterface added in case you have something that's implementing IList but doesn't have the IList type as it's first generic argument).
myobject.GetType().GetInterface("System.Collections.Generic.IList").GetGenericArguments()[0].IsEnum
You can look at the the indexer's PropertyType via Type.GetProperty:
List<int> list = new List<int>(); // an empty List<T>
Type type = list.GetType().GetProperty("Item").PropertyType; // System.Int32
bool isEnum = type.IsEnum; // of course false
List<DayOfWeek> days = new List<DayOfWeek>();
type = days.GetType().GetProperty("Item").PropertyType;
isEnum = type.IsEnum; // true
demo: http://ideone.com/3JyEf
Having just IList you can't do that - IList does not gurantee types of objects inside of it and does not let you know type of objects it would accept.
Consider uisng generic veriosn IList<T> if possible - you'll be able to get type without elements in the list.
Unless your list is a generic list you cannot, since a non generic list may contain any object.
If list is generic then inspect generic type parameters for enum types.
If list is not generic try to resolve item type by inspecting parameters of Add, IndexOf or indexer methods. It is a very ugly way to do it, but may give you a clue since many old implementations inherits List object and adds an Add overload, or some new and lazy implementations may be used to hide generic parameters like public class MyObjectList: List<MyObject> {}.
The solution everyone is proposing:
IList<Days> list = new List<Days>();
if (list is IList<Days>)
{
Console.WriteLine("list has days");
}

If method returns interface type, why can't I pass the result to a concrete type?

The question maybe a little confusing, but it's hard to make clear this question in a subject title.
I have method declared and implemented like this:
public IList<string> GetBookTitles()
{
IList<string> bookTitles = new List<string>();
// do something to populate the bookTitles list.
return bookTitles;
}
Why can't I pass the result of this method to a List<string>? After all, List<string> is a kind of IList<string>.
Well, for starters, just look at the members of IList and compare it with List. List has methods that an IList doesn't. (List has a BinarySearch method that IList doesn't, just as a single example.)
Arrays also implement IList, as an example. An array however is not a List, so you can't, and shouldn't, be able to pass a string[] to a method that accepts a List<string>.
You have a few possible solutions. One would be to just change your method to return a List<string> rather than an IList<string> (that's what I'd suggest). If that's what you really need then you shouldn't be restricting the return type to IList<string>. Another (poorer) option would be to cast the result back to a List<string> before passing it to the next method, since you happen to know that it's what the underlying type really is.
After all, List<string> is a kind of IList<string>.
But there are also other kinds of IList<String>.
What if your method were to return an IList<String> which is a ReadOnlyCollection<String> instead?
IList<string> x = new ReadOnlyCollection<string>();
List<string> y = x; //Huh?
The compiler uses the signature of your methods, not the implementation when deciding if you can assign the result of GetBookTitles to your variable, so it can't know that the result will in fact be a List. If it would allow you to do such a thing, then you could write something like this:
List<string> myBooks = GetBookTitles();
myBooks.Sort();
In your example you could do this, and in fact you can if you cast the result of your method:
List<string> myBooks = (List<string>)GetBookTitles();
But then one day you could decide that your book collection is not modifiable, and you rewrite your method as follows:
public IList<string> GetBookTitles()
{
IList<string> tmp = new List<string>();
// do something to populate the bookTitles list.
IList<string> bookTitles = new ReadOnlyCollection<string>(tmp);
return bookTitles;
}
ReadOnlyCollection does not implement Sort, so your app would compile, but would crash at runtime.
Using the cast approach it would crash when trying to do the cast, but in this case you are taking the responsibility of deciding that that kind of cast is feasible and do not have the compiler trying to guess.
A better approach could be to use as instead of the cast and chek for null. I.e.:
List<string> myBooks = GetBookTitles() as List<string>;
if (myBooks != null)
myBooks.Sort();
You should be able to, you just need an explicit conversion.
List<string> foo = (List<string>)GetBookTitles()
should do it.
The interface may be implemented in various classes which are not same. So, it will be difficult to find the respective class.
You can type cast from IList to List!!!

C# convert reflection.propertyinfo to Generic.List<>

How do I go about converting a reflection.propertyinfo[] to a generic.list<>?
One of the List<T> constructors accepts an IEnumerable<T> as its argument (i.e., your PropertyInfo array):
var list = new List<PropertyInfo>( propInfoArray );
var list = yourArray.ToList();
Try using .ToList()
http://msdn.microsoft.com/en-us/library/bb342261.aspx
All of the above are correct. But it should also be mentioned that, like List<T> all .net arrays implement IList<T>.
var IList<PropertyInfo> ilist = reflection.propertyinfo;
Since I know that, almost all my functions accept IList<T> when I need a list-like collection, which I can use with traditional arrays and lists.
Use the extension method ToList() available in the System.Linq namespace:
var myProperties = propertyInfoArray.ToList();

Categories

Resources