AngryHacker
AngryHacker

Reputation: 61606

How can implement an extension method that takes descendants of the base class?

I have the following code:

public class MsgContract {
  public virtual string ToJson() {
      return genJson();
  }
}

public class A: MsgConract {
  ...
}

public class B: MsgConract {
  ...
}

public class ExtentionMethods {
  public static string ToJson(this List<MsgContract> lst) {
     foreach (var item in lst)
        string entry += item.ToJson();

     return entry;
  }
}

void Main() {
  List<A> lst = new List<A>();
  lst.ToJson();    // error
}

Seems that the extension method only accepts List but not a list of the descendants of MsgContract.

Conceptually I understand why this is so. However, are there workarounds?

Upvotes: 0

Views: 101

Answers (2)

Reza ArabQaeni
Reza ArabQaeni

Reputation: 4907

List<T> is not a covariant projection, So recommended use IEnumerable<T> that type parameter is covariant.

  public static string ToJson(this IEnumerable<MsgContract> lst) {
     foreach (var item in lst)
        string entry += item.ToJson();

     return entry;
  }

Upvotes: 3

Brian Driscoll
Brian Driscoll

Reputation: 19635

I'd recommend using a generic type parameter and constraining it to your MsgContract class, like this:

public class ExtentionMethods {
  public static string ToJson<TContract>(this List<TContract> lst) 
      where TContract : MsgContract
  {
     foreach (var item in lst)
        string entry += item.ToJson();

     return entry;
  }
}

Upvotes: 2

Related Questions