tags:

views:

75

answers:

2

Let me start by saying I'm pretty new to using interfaces.

I'm writing a method (GetClaimDetails) that will return information about a medical insurance claim. If it is claim type A, it will return an list of the ClaimDetailA class. If claim type B, return list of ClaimDetailB class. Both of these classes share common properties but each have unique properties. The common properties are implemented in an interface.

I extracted an interface named IClaimDetail and set both to implement it. When i set the method to return IClaimDetail and have it return an instance of an object that implements IClaimsDetail, I get the compiler message

'Cannot implicitly convert type 'System.Collections.Generic.List DentalClaimDetail' to 'System.Collections.Generic.List IClaimDetail'

  private static List<IClaimDetail> GetClaimDetailsB(string claimNumber, string connectionStringName)
        {

          var claimReportRows = new List<DentalClaimDetail>();
      ..removed for brevity
      return claimReportRows;
    } 



   public class DentalClaimDetail : IClaimDetail
    {
    ...
    }

When a method returns an interface, you just return an object the implements the interface. Correct? What am I doing wrong?

+7  A: 
var claimReportRows = new List<IClaimDetail>();

Just change this. Then you will be able to insert DentalClaimDetail into it still.

Daniel A. White
Wow. easy enough. Thanks!!
asp316
@asp316 - Don't just change your code without understanding WHY you need to do this. Read Eric Lippert's series about covariance and contravariance (blogs.msdn.com/ericlippert/archive/…) starting at part 1, which explains why you probably think your code should work, through up to part 11, which will explain why it doesn't, but why similar things will in C# 4.0.
Greg Beech
Sorry, actual link: http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
Greg Beech
This article is good stuff. Makes my brain hurt but will really shed some light on what's going on here. Thanks Greg! –
asp316
+1  A: 

Generics actually generate an type on-the-fly at compile time for every generic argument, so List<IClaimDetail> is one type, and List<DentalClaimDetail> is actually another type, so you will get compiler errors for that.

Yes, lame, but simply changing your call as outlined by Daniel A. White

var claimReportRows = new List<IClaimDetail>();

(although you should just be able to use the type directly unless you are using Linq) and then having the code use casting to cast the DentalClaimDetail to an IClaimDetail should do the trick. If not using Linq, you can do something like:

List<IClaimDetail> claimReportRows = new List<IClaimDetail>();
//...populate Dentail Claims Here...
foreach(DentalClaimDetail dcd in dentalClaims)
{
  claimReportRows.Add((IClaimDetail)dcd);
}
return claimReportRows.

Hope this helps!

Tony Heupel