-1

Departing point is that I have an interface with generics with 2 implementations:

Interface:

interface IFoo<T , U>
{
    U Method1(T item);
    T Method2(U id);
}

Implementations:

public class Type1 { }

public class Implementation1 : IFoo<Type1, int> {
    public int Method1(Type1 item)
    {
        throw new NotImplementedException();
    }

    public Type1 Method2(int id)
    {
        throw new NotImplementedException();
    }

    //....
    public int Method3()
    {
        int myReturnedInt = 0;
        //....

        return myReturnedInt;
    }

   

    public void Method4()
    {

    }
}
 
public class Type2 { }

public class Implementation2 : IFoo<Type2, int> {
    public int Method1(Type2 item)
    {
        throw new NotImplementedException();
    }

    public Type2 Method2(int id)
    {
        throw new NotImplementedException();
    }

    public int Method3()
    {
        int myReturnedInt = 0;
        //....

        return myReturnedInt;
    }

    public void Method4()
    {

    }
}

With this departing point, supposed that I got my instances of each of the implementation types available, I would like to map each instance in a dictionary, to acces to the respective Method3 and Method4 respectively, so I tried:

Group both of the types and abstract from generics:

public interface IContainerInterface : IFoo<Type1, int>, IFoo<Type2, int>
    {
        int Method3();
        void Method4();
    }

Fill the dictionary in:

public enum EnumType
    {
        type1,
        type2
    }

    Implementation1 type1Instance;
    Implementation2 type2Instance;

    private Dictionary<EnumType, IContainerInterface> _container;

    void Main(string[] args)
    {
        _container = new Dictionary<EnumType, IContainerInterface>{
            {EnumType.type1, type1Instance as IContainerInterface},
            {EnumType.type2, type2Instance as IContainerInterface}
        };
    }

But does not work. Although Implementation1Instance is available, the value in the dictionary is null. A working example of this with no generics would be the answer to this question, where the binding from interface to implementation is achieved when there are no generics involved, but how to achieve this with generics in the interface?

My objective is to be able to access to the methods of the types respectively like this:

//for type1
int myInt = _container[EnumType.type1].Method3();
_container[EnumType.type1].Method4();
//for type2
int myInt = _container[EnumType.type2].Method3();
_container[EnumType.type2].Method4();

Edit:

Corrected all the typos in the read through and find the full compiling snippet (not to be executed, but to be able to understand and follow along what the problem Im trying to explain):

using System;
using System.Collections.Generic;

namespace ConsoleApp10 {

    public interface IFoo<T, U>
    {
        U Method1(T item);
        T Method2(U id);
    }

    public class Type1 { }

    public class Implementation1 : IFoo<Type1, int>
    {

        public int Method1(Type1 item)
        {
            throw new NotImplementedException();
        }

        public Type1 Method2(int id)
        {
            throw new NotImplementedException();
        }

        //....
        public int Method3()
        {
            int myReturnedInt = 0;
            //....

            return myReturnedInt;
        }

       

        public void Method4()
        {

        }
    }

    public class Type2 { }

    public class Implementation2 : IFoo<Type2, int>
    {
        public int Method1(Type2 item)
        {
            throw new NotImplementedException();
        }

        public Type2 Method2(int id)
        {
            throw new NotImplementedException();
        }

        public int Method3()
        {
            int myReturnedInt = 0;
            //....

            return myReturnedInt;
        }

        public void Method4()
        {

        }
    }

    class Program
    {
        public interface IContainerInterface : IFoo<Type1, int>, IFoo<Type2, int>
        {
            int Method3();
            void Method4();
        }

        public enum EnumType
        {
            type1,
            type2
        }

        Implementation1 type1Instance;
        Implementation2 type2Instance;

        private Dictionary<EnumType, IContainerInterface> _container;

        void Main(string[] args)
        {
            _container = new Dictionary<EnumType, IContainerInterface>{
                {EnumType.type1, type1Instance as IContainerInterface},
                {EnumType.type2, type2Instance as IContainerInterface}
            };
        }
    }
}
rustyBucketBay
  • 4,320
  • 3
  • 17
  • 47
  • I don't see why you need the generic, those generic types aren't used at all in your code. Also, your code is rifled with syntax errors (missing return types, assignments at the class level, etc). It makes it difficult to even attempt to guess what mess you're trying to make here. – Blindy Mar 22 '21 at 16:57
  • I know the issue might be a bit complex. I tried to post only the meaninful code and as simplified as possible. I will try to fix the sample snippets as much as possible for the typos. Generics are already in the scenario, it can be supposed that apart from the appropiate of their usage they are part of their respective types implementation, are used there and are part of the problem in the encountered scenario. Thanks for your commnet :) – rustyBucketBay Mar 22 '21 at 17:00
  • Casting with `as` will return `null` if the object doesn't implement the type you want to cast to. It's called safe casting. And from your example, both Implementation1 and Implementation2 don't implement `IContainerInterface` – treze Mar 22 '21 at 17:03
  • `generic types aren't used at all in your code` All the implementation of the interfaces is not posted, but in the rest of the implementation the generics are used, however to post that part of the code does not provide any insight towrds the problem – rustyBucketBay Mar 22 '21 at 17:03
  • If you are going to call the same method on each implementation (i.e. it has the same name, takes the same parameters and has the same return type) then extract that method into a non-generic interface. If you are going to be calling a method with different signatures, then you have much bigger problems to worry about. How would you even call it or work with the returned value. – DavidG Mar 22 '21 at 17:05
  • @DavidG, that is what I tried with `private interface IContainerInterface: IFoo, IFoo` but then dont know how to fill the dictionary in – rustyBucketBay Mar 22 '21 at 17:07
  • No, `IFoo<>` should implement `IContainerInterface`, and `IContainerInterface` should contain the signatures for the methods you want to call. – DavidG Mar 22 '21 at 17:08
  • Question edited correcting typos (I was providing kind of pseudocode to read along) and compiling snippet provided. Sorry for that – rustyBucketBay Mar 22 '21 at 17:28

1 Answers1

1

If what you're trying to do here is to is to define an interface just to hold these types polymorphically, and you are able to define a fully working, non-generic interface that provides all the required functionality, then you're handling this the wrong way around.

Instead of writing this absolutely wrong, error-prone and short sighted monstrosity (what happens when you need more types, whatever they are? which interface are you implementing the same-named functions for? etc etc):

interface IContainerInterface: IFoo<Type1, int>, IFoo<Type2, int>

What you should do is define an IContainerInterface at the very root of the inheritance tree, then derive IFoo<> from it. Your dictionary initialization and usage remains identical, and you no longer need to change the interface every time you need a new type.

All the implementation of the interfaces is not posted

Of course, that's if you can extract a non-generic interface from your code. It's anyone's guess, because you certainly don't provide relevant and/or correct code at all.

Blindy
  • 65,249
  • 10
  • 91
  • 131
  • `define an interface just to hold these types` this is exactly what im trying to do. I will give a try for your piece of advice. Thanks – rustyBucketBay Mar 22 '21 at 17:11
  • typos corrected and compiling snippet provided – rustyBucketBay Mar 22 '21 at 17:29
  • seems that my mistake was that I was trying to extend the interface down the hierarchy instead of as you adviced `define an IContainerInterface at the very root of the inheritance tree`. This is a key concept for me, as I did not get to understand the biniding between the interfaces and respective implementations, the same as the definition of interface types and holders for their respective implementstions. You grasped the key of my problem even from among all the monstruosity, thanks a lot! :) – rustyBucketBay Mar 22 '21 at 17:56
  • 1
    Generic (`object`) to specialized (your concrete type) is the rule! – Blindy Mar 22 '21 at 17:59