views:

160

answers:

4

I get a compile error, "Cannot implicitly conver type 'System.Collections.ObjectModel.ObservableCollection to ProddataRecsObservable'. An explicit conversion exists" See comments in following code segments.

//I created a custom class called ProddataRecsObservable derived from
//ObservableCollection<Proddata> so I can do some special CRUD operations for my production
//data records.

public class ProddataRecsObservable : ObservableCollection<Proddata>
{

}        

//I have another class which maps an object to a reader and the function MappAll returns an 
//Observable collection of type <T>.

public abstract class MapperBase<T>
{
    protected abstract T Map(IDataRecord record);

    public ObservableCollection<T> Mapall(IDataReader reader)
    {
        ObservableCollection<T> collection = new ObservableCollection<T>();

        while (reader.Read())
        {
            try
            {
                collection.Add(Map(reader));
            }
            catch
            {
                throw;
            }
        }

        return collection;
    }
}

//I have another class derived from MapperBase called ProddataMapper.

public class ProddataMapper : WTS.Data.Mapper.MapperBase<Proddata>
{
    protected override Proddata Map(System.Data.IDataRecord record)
    {
        Proddata p = new Proddata();    

        p.PSTAT = (DBNull.Value == record["PSTAT"]) ? "" : record["PSTAT"].ToString();

 return p;
    }
}

//In my calling code, I attempt to set a ProddataRecsObservable variable equal to the 
//result of MapAll() from my ProddataMapper class but get the compile error. The error even 
//tells me they are the same type which is strange. How can I get around this?

//Calling Code:

ProddataMapper prodMapper = new ProddataMapper(); 
ProddataRecsObservable recs = prodMapper.Mapall(ProddataReader); //ERROR'S HERE <-
+5  A: 

I don't see that it tells you the types are the same at all. ProddataRecsObservable isn't the same thing as ObservableCollection<Proddata> - what makes you think they're the same type? The first type derives from the second type - that doesn't make them the same type.

Every instance of ProddataRecsObservable is an instance of ObservableCollection<Proddata> due to the inheritance relationship, but the reverse isn't true.

What's you're doing is the equivalent of:

class Test : object {}

object Foo()
{
    return new object();
}
...
Test t = Foo();

Would you expect that to work? If so, why would you expect it to work? How is the compiler meant to know that Foo will actually return an instance of Test (which in fact it doesn't here - nor does your method return an instance of your derived class)? If you wouldn't expect that to work, why would you expect your example code to work?

Jon Skeet
+1 for drive to why by returned to the basics. Don't give me a fish teach me how to fish
Abdullah BaMusa
+2  A: 

ObservableCollection<Proddata> cannot be upcasted to ProddataRecsObservable, there is additional logic in ProddataRecsObservable that ObservableCollection<Prodddata> doesn't know about.

Stan R.
+1  A: 

Make MapAll() abstract in the base class, and then in the ProdDataMapper provide the override:

public override ProddataRecsObservable Mapall(IDataReader reader)
{
   // do the downcast explicitly
    return (ProddataRecsObservable) base.MapAll(reader);
}
Phillip Ngan
A: 

John Skeet is right. Try explicitly casting the result to ProddataRecsObservable in the assignment where you get the error.

Phillip Ngan