Converting arraylist into List in c# - c#

I have an arraylist named "ObjectArray" , to do some perfomance improvement and get rid of casting issues , I thought of to use Generic List, how can I convert following arralist to List? I know ToList() will do but how to do in this scenario
public class ObjectArray : ArrayList
{}
ObjectArray col = ObjectArray.Deserialize(xml, Type.type);
Testobject tmo;
tmo= (Testobject)col[i];

You should not be inheritting from List<T>, but Collection<T> instead. Per MSDN docs:
System.Collections.Generic.List is a generic collection designed for
performance not inheritance and, therefore, does not contain any
virtual members.
The Collection class can be used immediately by creating an instance
of one of its constructed types; all you have to do is specify the
type of object to be contained in the collection. In addition, you can
derive your own collection type from any constructed type, or derive a
generic collection type from the Collection class itself.
Inherit from Collection as follows. Inside your class, you can then override (if needed) the basic collection behavior and/or add your own implementation.
public class ObjectArray : Collection<T>
See http://msdn.microsoft.com/en-us/library/ms132397(v=vs.80).aspx

Stop for a second; you are trying to have one class do two things. You are also moving compile-time problems to run-time. I would suggest you deserialize strong types and store them in strongly typed lists rather than everything in one.
i.e.
ViewModel[] viewModels= Serializer.DeserialiseViewModels(fromSomething);
DataModel[] dataModels= Serializer.DeserialiseDataModels(fromSomething);
In anycase, you are concerned with deserializing types and adding them to a list. So don't bother with a new collection class because you don't need to reinvent the wheel here.
SO lets assume you've deserialised an array of objects i.e.
object[] loaded = ObjectArraySerializer.Deserialise(fromSomething);
Now you want to get all the items of type T1 and T2
List<T1> itemsT1 = loaded.OfType<T1>().ToList()
List<T2> itemsT2 = loaded.OfType<T2>().ToList()
Now assuming
where T1: TBase, where T2: TBase
you can do
List<TBase> TBaseItems = itemsT1.Cast<TBase>().Concat(itemsT2.Cast<TBase>()).ToList();
or you could do that straight off the bat;
List<TBase> tbaseItems= loaded.OfType<TBase>().ToList();

Related

Get a List<Type> of all derived types in a list of objects that inherit from an abstract class

I've seen a bunch of questions dealing with getting all types from a base type and so on, but that's not quite what I need. For instance, I have and abstract base class:
public abstract class BasePart
{
//whatever
}
And I have a bunch of classes that derive from it. Like...
public class HorizontalPanel : BasePart { //code }
public class VerticalPanel : BasePart { //code }
public class RainBoard : BasePart { //code }
And so on.
I always list them by the base class:
List<BasePart> parts;
And I use typecasting and generics to do whatever I want with them. However, I came to a point where I need to filter this list and I only want the type information available in it. And only once for type. For instance, if my list has three HorizontalPanels and two VerticalPanels, what I want from it is a List<Type> that only contains {HorizontalPanel, VerticalPanel}. I suppose I can mess around with the objects themselves in chained loops to get what I want, but I'm positive that C# has a better way to do it. Anyone?
There is no language feature to help you with this. The simplest way would be to use LINQ, first use Select to get all the types and use Distinct
parts.Select(x => x.GetType()).Distinct();
You can use Object.GetType() to retrieve the type of the object and populate a list.
Afterwards, since you need a list which contains only one instance of each type, you can call Enumerable.Distinct() on the list you populated previously, and Enumerable.ToList() to convert the resulting enumerable to a list.
All in all, the code will be something akin to:
List<Type> types = new List<Types>();
foreach (Base element in MyList){
types.add(element.GetType());
};
List<Type> unique_types = types.Distinct().ToList();
Which will give you the list unique_types filled with exactly one instance of each type present in MyList.

Passing an ObservableCollection<child> to a function that take ObservableCollection<parent>

So I have a
BaseClass
and several child classes that inherit from the baseclass
ChildClass1
ChildClass2
I have ObservableCollections of child classes that need to be sorted in place, I cannot create a new ObservableCollection<ChildClas1>.
So i wrote a function
private void Reorder(ObservableCollection<BaseClass>)
{
//sort the collection in place
}
then i do Reorder(ObservableCollection<ChildClass1>)
the compiler is complaining that it cannot convert
System.Collections.ObjectModel.ObservableCollection<ChildClass1> to ObservableCollection<BaseClass>
I will take the compilers word for it, but how can I achieve this without having to duplicate my reorder function for every single child type?
I will take the compilers word for it
The reason why you cannot pass a collection of one type to substitute for a collection of another type is discussed in many Q&As on SO - for example, here.
how can I achieve this without having to duplicate my reorder function for every single child type?
One approach is to make your Reorder generic on the type of collection element, and add a constraint to the type parameter to specify that objects must derive from your base class:
void Reorder<T>(ObservableCollection<T> collection) where T : BaseClass {
...
}

C# list of "Type" that implements specific interface

I want to create a List<System.Type> listOfTypesOfGlasses , where Type must implement a specific interface IGlass , so I could load it with Types of glasses.
Is there a way to enforce in compile time this constraint(must implement IGlass) ?
Implement a method/class that hides the list.
class YourClass {
// intentionally incomplete
private List<Type> listOfTypesOfGlasses;
public void AddToList<T>() : where T: IGlass
{
listOfTypesOfGlasses.Add(typeof(T));
}
}
Edit: below is the original answer here assuming that Type meant a placeholder, not System.Type.
All you should need to do is List<IGlass>.
or
You should write your own wrapper class around List<T> that has the constraint.
or
Subclass List<T> and put the generic constraint on it - however this practice is discouraged.
No - typeof(IGlass) and typeof(Glass) are both Type objects - not different classes that can be filtered in a generic constraint. There's no generic restriction that works off of the values stored. If you want to store instances of types that all implement IGlass that's possible, but you can;t filter the actual Type objects that can be stored.

List of generic objects with unknown type

I have the following two classes. The ConvertToType<T> class is an existing class and works fine, however when it is used an instance is created each time (via reflection), therefore I am creating a wrapper class to hold all the instances as they are created for efficiency.
public class TypeConverterHelper
{
private IList<ConvertToType<>> types;
}
internal class ConvertToType<T>
{
//snip
}
However, as you can see I need a list of my ConvertToType<T> class, but I can't specify the type as the whole point of these classes is that the type is unknown until runtime. I have researched this issue a fair amount, but without finding a successful solution. I know I could set the generic type to be an object, but there you could get un/boxing issues at some point. Adding an interface/abstract base class which is restricted to a struct looked like a good option, but unfortunately T could be a string, and possibly other custom classes at a later date so that solution doesn't work.
So does anyone have any other solutions/suggestions?
The list type has to be non-generic (since the generic type arguments cannot be predicted), so object would do, but it might be better to use a common non-generic base. Boxing/unboxing does not come into the discussion because ConvertToType is a reference type.
You would of course have to cast the values in the list back to ConvertToType<T> before being able to use them; the implementation could look like this:
public class TypeConverterHelper
{
private IList<object> types;
public ConvertToType<T> GetConverter<T>()
{
return types.OfType<ConvertToType<T>>.FirstOrDefault();
}
}

How to let a method accept two types of data as argument?

I have a method, accepting a Hashtable (yes I know, it's outdated..) as argument:
public static LuaTable HashtableToLuatable(Hashtable t, int depth = 1)
This works correctly.
Now I'd like to accept an ArrayList as first parameter as well, so you can let 't' have the value of both a Hashtable and an ArrayList. Currently I have copy-pasted the method two times, like this:
public static LuaTable ArraylistToLuatable(ArrayList t, int depth = 1)
The rest is exactly the same.
I think there's a way to merge this.
Both classes implement the ICollection interface, so if your 'common code' will work against the definition of the ICollection interface, you could use that for your parameter type.
Both types implement IEnumerable and ICollection, so rewrite your method signature to use one of those instead:
public static LuaTable EnumerableToLuaTable(IEnumerable t, int depth = 1)
or
public static LuaTable CollectionToLuaTable(ICollection t, int depth = 1)
I'd prefer the IEnumerable option over ICollection, if you don't need anything in ICollection.
You have shown an example of method overloading, and so far what you are doing works within the framework of C#.
The question is, what what must the method do with the passed-in value. There must be some means of treating them as "equivalent". One way to do that is if both types implement the same interface.
ArrayList implements: IList, ICollection, IEnumerable
Hashtable implements: IDictionary, ICollection, IEnumerable
If the code inside your method body just treats the first argument like a collection, you can change the method signature to:
public static LuaTable HashtableToLuatable(ICollection t, int depth = 1)
If your implementation does not use or require everything in ICollection, you could instead specify
public static LuaTable HashtableToLuatable(IEnumerable t, int depth = 1)
More objects implement IEnumerable than ICollection, so using IEnumerable (if possible) will allow for greater flexibility down the road to pass in a different type of object.
Both of these (terribly outdated) types implement two common interfaces, namely; IEnumerable and ICollection. So, you can set a generic constraint based on on of those interfaces.
static void ArraylistToLuatable<T>( T collection ) where T : IEnumerable
{
foreach( var item in collection )
{
// do something
}
}
Of course, this still sucks, because item is going to be of type object, which will work better for your ArrayList argument than your HashTable argument as, under the covers, you have to deal with a DictionaryEntry somehow, which means you have to check its type in the method and cast your item appropriately.
Are you sure you can't use a more up to date generic collection type? Would it be possible to wrap them in a generic collection as you get them from your DLL? I suppose it depends on how much of this sort of thing is needed on your end. If it's just one or two methods it's probably fine this way.
You could try generics, if that works for you..
public static LuaTable <T> HashtableToLuatable(T t, int depth = 1) where T : ICollection
You may also derive your own datatypes if the above does not fit your case..

Categories