-1

I want to create an extension method with generics. But when using this method I get the error Compiler Error CS0311. How can I solve this? Here's an example.

using Compare;
using System.Collections.ObjectModel;

static class Program
{
    static void Main()
    {
        var OldItemListe = new LoadListe();
        var NewItemListe = new LoadListe();
        bool ReturnValue = new Import().Compare(OldItemListe, NewItemListe);  //Here I got the Error CS0311
    }
}

namespace Compare
{
    /// <summary>Baseclass for all Elements </summary>
    public class BaseClass
    {
        /// <summary> Elementname </summary>
        public string Name { get; set; }
        /// <summary> Beschreibung </summary>
        public string Description { get; set; }
    }
    public abstract class BaseListe<T> : Collection<T> where T : BaseClass, new() { }
    public class Load : BaseClass{}
    public sealed class LoadListe : BaseListe<Load> {}


    public class Import
    {
        public bool Compare<U>(U OldItemListe, U NewItemListe) where U : BaseListe<BaseClass>
        {
            // do something
            if (OldItemListe[1].Name == NewItemListe[1].Name) return true; // only Example
            return false;
        }
    }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Steffen_dd
  • 59
  • 8
  • Maybe [the documentation for error CS0311](https://learn.microsoft.com/en-us/dotnet/articles/csharp/language-reference/compiler-messages/cs0311) helps? – Uwe Keim May 19 '17 at 07:15
  • 4
    Just because two types, `T1` and `T2` have a particular inheritance relationship, that *does not* means that a generic type instantiated with those types (`G` and `G`) has the *same* inheritance relationship. In fact, there is *no* inheritance between those instantiated types. – Damien_The_Unbeliever May 19 '17 at 07:16
  • Is there a way to solve this? The documention doesn't help me. I have passed the Compare method synonymous already objects, but then I get a Cast Error when I caste this into a BaseListe. – Steffen_dd May 19 '17 at 07:22
  • `Collection` is not read-only, so you have a constraint problem when `adding` an element of base type to a collection of derived type. Can you use a read-only collection type instead? – Bernhard Hiller May 19 '17 at 07:32
  • I think no, bacause in the end I would like to use the Compare method to delete all elements which are equal in both lists. – Steffen_dd May 19 '17 at 07:45
  • You have asked the same "I'm trying to sneak base class items into my derived type list" question that has been asked countless times already. And the answer is still the same. See marked duplicate. The way you are trying to use these types currently is not type-safe. And unless you change your goal, you won't be able to get it to work, because the compiler is saving you from yourself on purpose. If you can reframe your design so that it's type-safe, you can get it to work. But that would depend on a lot more information than you've shared here. See "generic type variance" for details. – Peter Duniho May 19 '17 at 08:06

1 Answers1

0

This most probably creates other problems to be solved but could you do something like:

public class GBase
{
    public string Name { get; set; }
}

public class GLevel1 : GBase
{

}

public class GLevel2 : GBase
{

}


public class CollectionBase<T> : Collection<T> where T : GBase
{ }

public class CollectionLevel0 : CollectionBase<GBase>
{

}

public class CollectionLevel1 : CollectionLevel0
{

}

public class Comparer
{
    public bool Compare<T>(T old, T newer) where T : CollectionLevel0
    {
        return old[0].Name == newer[0].Name;
    }
}

You can then use it like:

var col1 = new CollectionLevel0();
var col2 = new CollectionLevel0();
col1.Add(new GLevel1() { Name = "Dave" });
col2.Add(new GLevel2() { Name = "Bob" });

var col3 = new CollectionLevel1();
col3.Add(new GLevel1() { Name = "Billy" });
var col4 = new CollectionLevel1();
col4.Add(new GLevel1() { Name = "Billy" });

Comparer a = new Comparer();
bool b1 = a.Compare<CollectionLevel0>(col1, col2);
bool b2 = a.Compare<CollectionLevel1>(col3, col4);
Scrobi
  • 1,215
  • 10
  • 13
  • Ok, this functionality I already have at the moment. My problem is that I have the Compare function in approximately 30 collenction classes (all come from the BaseClass), with the identical code and this code I wanted to put in a seperate method. Apparently this is not so easy. – Steffen_dd May 19 '17 at 08:15
  • Your collection classes can all inherit from CollectionLevel0 and then still use same Comparer function. – Scrobi May 19 '17 at 08:22