1

I have 2 ObservableCollections, say of type class1 and class2.

private ObservableCollection<Class1> cOne; // collection of objects of type Class1
private ObservableCollection<Class1> cTwo; // collection of objects of type Class2

Now in the below method I want to iterate over this collections and access object's members.

public void MyMethod<T> (){
    var listOfLayers = new ObservableCollection<T>();

    if (typeof(T) == typeof(Class1))
    {
       listOfLayers = (T) cOne;    
    }
    else{
       listOfLayers = (T) cTwo;  
    }

    foreach (var entry in listOfLayers){
        WL entry.someprop;
    }

}

But it throws me error every time about type conversion.

Error CS0030 Cannot convert type 'System.Collections.ObjectModel.ObservableCollection' to 'T'

Please note that I haven't created two methods based on type because both methods essentially going to do the same thing in separate database tables. And hence they both gonna contain the duplicate code.

Florian Moser
  • 2,583
  • 1
  • 30
  • 40
Jadav Bheda
  • 5,031
  • 1
  • 30
  • 28

3 Answers3

1

Your are trying to cast some that is of type T (T) cOne; to something that is of type ObservableCollection<T> this is why you get the error. This means cOne should be cast to ObservableCollection<T>

Gerben
  • 363
  • 1
  • 7
0

You should probably cast to ObservableCollection<T> and not simply T. You corrected code:

public void MyMethod<T> (){
    var listOfLayers = new ObservableCollection<T>();

    if (typeof(T) == typeof(Class1))
    {
       listOfLayers = (ObservableCollection<T>) cOne;    
    }
    else{
       listOfLayers = (ObservableCollection<T>) cTwo;  
    }

    foreach (var entry in listOfLayers){
        WL entry.someprop;
    }
}

As a side node, your code looks a bit strange. This could also be because you've simplified the example to prove your point, but still: cOne will already be of the correct type, so why do you cast it?

If you want to use the methods of T typesafe it would probably be better to create an own method for each ObservableCollection<T> you want to support, so you do not have to pass a type to execute it. I'm guessing you also want to execute different logic for different T so splitting this would make sense.

Florian Moser
  • 2,583
  • 1
  • 30
  • 40
  • Thanks Florian for your great answer. I did the suggested changes however it still throws same error: "'System.Collections.ObjectModel.ObservableCollection' to 'System.Collections.ObjectModel.ObservableCollection' ". I think I better create two separate methods now however they will contain more or less the same code. – Jadav Bheda May 22 '17 at 23:13
  • are you sure this exception is not happening in the else branch? So could it be that `typeof(T) != typeof(Adjust‌​IT.Landbase)`? – Florian Moser May 23 '17 at 07:27
  • Be aware that you can not cast to base types (so if `T` is a parent class of `AdjustIT.Landbase` the cast will fail), see this answer why not: https://stackoverflow.com/a/43378505/2259391 – Florian Moser May 23 '17 at 07:29
0

The way you do the cast is not right. It should read listOfLayers = (ObservableCollection<T>) cOne, since listOfLayers is an ObservableCollection<T>, rather than T.


It's unclear to me why you need the cast though. You could just pass cOne and cTwo as arguments to the the method, and get by with much cleaner code. I bet Class1 and Class2 are somehow related, so they might share a common base class or interface, and you could make the argument ObservableCollection<IBaseClass>.

Horia Coman
  • 8,681
  • 2
  • 23
  • 25
  • Class1 and Class2 are infact Model classes. They represents database tables. The method where I tried casting is basically doing few database queries and initializes the ObservableCollection. – Jadav Bheda May 24 '17 at 00:15