-7

I have these multiple versions of these two classes:

public class Contests : List<Contest> { }

public class Contest {

    // stuff specific to Contest;       

    public Contests parent;

    public void Attach() {
        parent.Add(this);
    }
}

And here's another:

public class Transactions : List<Transaction> { }

public class Transaction {

    // stuff specific to Transaction;       

    public Transactions parent;

    public void Attach() {
        parent.Add(this);
    }
}

So that I don't repeat code, can I take out the Attach into a base class using generics?

public class MBData<T> {

    public T parent;

    public void Attach() {
        T.Add(this);
    }
}

I tried with the following but I receive an error about not being able to convert between Contests and MBDatas<MBData<Contests>>.

public class MBDatas<S> : List<S> { }

public class MBData<B> where B : MBDatas<MBData<B>> { }

public class Contests : MBDatas<Contest> { }

public class Contest : MBData<Contests> { }
CapIsland
  • 129
  • 1
  • 9
  • 4
    Gives an error? What is the error?! – DavidG Aug 20 '18 at 23:56
  • Specifying which error is raised would be useful to everyone. Also, what are you trying to achieve exactly ? – Pac0 Aug 20 '18 at 23:56
  • also, related: [Why not inherit from List](https://stackoverflow.com/questions/21692193/why-not-inherit-from-listt) and [Is it good practice to inherit from generic type, Software Engineering.SE](https://softwareengineering.stackexchange.com/questions/266672/is-it-good-practice-to-inherit-from-generic-types) – Pac0 Aug 20 '18 at 23:57
  • Specifically, you failed to mention the error – Ňɏssa Pøngjǣrdenlarp Aug 20 '18 at 23:57
  • Also, it would be good to specify which C# language version you are using for this question. – Pac0 Aug 21 '18 at 00:04
  • Hi could you re-write the question but this time include what errors you are getting and where please. We can all answer better with this information. – GIVE-ME-CHICKEN Aug 21 '18 at 00:06
  • While trying hard to understand why you would write such a thing, and trying to reproduce on an online compiler (https://dotnetfiddle.net/), I was wondering : how would you expect the second line to compile ? You're constraining B to be something.... in terms of B. And also, the last two lines look like pretty simple circular reference for the compiler to detect, while the other seem like some intricated nonsense that even the compiler fails to detect quickly. – Pac0 Aug 21 '18 at 00:08
  • OP, in generics, a `Generic` is not related to a `Generic` in any way, shape, or form. It is not an ancestor and they can't be subsituted for one another unless you have set up [covariance](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/). You are trying to use a `Contest` where an `MBData` is needed, hence the compilation error. – John Wu Aug 21 '18 at 00:26
  • @JohnWu - That doesn't seem to be what the OP is trying to do in my mind. – Enigmativity Aug 21 '18 at 06:33
  • I have edited my post to explain things more. – CapIsland Aug 21 '18 at 07:25

1 Answers1

-2

Does this work for you?

public abstract class MBData<P, C>
    where P : MBDatas<P, C>
    where C : MBData<P, C>
{
    public void Attach()
    {
        this.Parent.Add((C)(object)this);
    }
    public P Parent { get; set; }
}

public abstract class MBDatas<P, C> : List<C>
    where P : MBDatas<P, C>
    where C : MBData<P, C>
{ }

You are forced to do a nasty double cast (C)(object)this to get the Attach method to work and this is the only rub with this approach. It works, but you need to be careful that you define the child classes properly.

You can define your classes like this:

public class Contests : MBDatas<Contests, Contest> { }
public class Contest : MBData<Contests, Contest> { }
public class Transactions : MBDatas<Transactions, Transaction> { }
public class Transaction : MBData<Transactions, Transaction> { }

And finally, use them like this:

var cs = new Contests();
var c1 = new Contest() { Parent = cs };
var c2 = new Contest() { Parent = cs };

cs.Add(c1);
cs.Add(c2);

var ts = new Transactions();
var t1 = new Transaction() { Parent = ts };
var t2 = new Transaction() { Parent = ts };

ts.Add(t1);
ts.Add(t2);
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • 1
    How did you come to the conclusion that this is the answer to OP's need ? It's not answering the written question (which was *why* OP's code was generating error), and OP has not given any more feedback despite all the questions in comments. – Pac0 Aug 21 '18 at 00:46
  • @Pac0 - I understood that the OP was trying to make a list of `Contest` called `Contests`. This structure made it work. Simple as that. – Enigmativity Aug 21 '18 at 06:32
  • This did indeed remove the error, but it still does not help me achieve what I wanted, which is not your fault as I stupidly forgot to explain what I was trying to achieve. I have edited my post. – CapIsland Aug 21 '18 at 07:24
  • @CapIsland - I've just updated my answer. I think this is it. – Enigmativity Aug 21 '18 at 07:32
  • That compiles. However, a function: `public void func() {Parent.Add(this);}` works only in the Contest class, not in the MBData class, which is where it needs to be to be inherited. – CapIsland Aug 21 '18 at 08:30
  • @CapIsland - That's easy to fix. I'll fix it a bit later though. – Enigmativity Aug 21 '18 at 09:27
  • @Enigmativity Thanks for taking the time to do that. It's taught me quite a bit about generics. However, I might also try a different approach in my code that gets round the need for a child class to tinker with its parent list class. – CapIsland Aug 21 '18 at 16:16