0

Please tell me what I'm doing wrong. It is necessary to put in one dictionary various objects that implement one interface with a generic argument.

Here's the code for an example:

There is an interface and two implementations OneParameter and TwoParameter:

public interface IParameter
{
    string Name { get; }
}

public class ParameterBase : IParameter
{
    public ParameterBase(string name)
    {
        Name = name;
    }
    public string Name { get; }
}

public class OneParameter : ParameterBase
{
    public OneParameter(int oneProperty)
        : base("One")
    {
        OneProperty = oneProperty;
    }

    public int OneProperty { get; set; }
}

public class TwoParameter : ParameterBase
{
    public TwoParameter(int twoProperty)
        : base("Two")
    {
        TwoProperty = twoProperty;
    }

    public int TwoProperty { get; set; }
}

There are also two behavior strategies:

public interface IRequestStrategy<TRequestParameter>
    where TRequestParameter : IParameter
{
    Task RequestDocument(TRequestParameter parameter);
}

public class OneRequestStrategy : IRequestStrategy<OneParameter>
{
    public Task RequestDocument(OneParameter parameter)
    {
        throw new NotImplementedException();
    }
}

public class TwoRequestStrategy : IRequestStrategy<TwoParameter>
{
    public Task RequestDocument(TwoParameter parameter)
    {
        throw new NotImplementedException();
    }
}

Next, I try to register strategies in one dictionary:

private static void TestStrategies()
    {
        Dictionary<int, IRequestStrategy<IParameter>> _strategies = 
            new Dictionary<int, IRequestStrategy<IParameter>>();

        var str1 = new OneRequestStrategy();
        var str2 = new TwoRequestStrategy();

        _strategies.Add(1, (IRequestStrategy<IParameter>)str1);
        _strategies.Add(2, str2);
    }

In the first case, there is an error of type casting: Unable to cast object of type 'OneRequestStrategy' to type IRequestStrategy`1[IParameter]'.

In the second, it's the same only when compiling: Error CS1503 : cannot convert from 'TwoRequestStrategy' to 'IRequestStrategy<IParameter>'

Chelfree
  • 9
  • 4
  • 1
    https://ericlippert.com/category/covariance-and-contravariance/ – CoolBots Feb 28 '21 at 20:09
  • You can't cast the object because doing so would be unsafe and thus illegal. See duplicate for some details, and of course all the other questions and answers on the site, and elsewhere on the web, discussing generic type variance. – Peter Duniho Feb 28 '21 at 20:32
  • geesh.. cutting me off with closing question in the midst of an answer. @Chelfree, the reasoning\issue is infact provided in that duplicate.. but for your scenario, you would need only implement `IRequestStrategy` on `OneRequestStrategy` and `TwoRequestStrategy` and ensure that `RequestDocument(OneParameter parameter)` calls to `Task RequestDocument(IParameter parameter)` in the proper scope. That should also indicate why you're inhibited. – Brett Caswell Feb 28 '21 at 20:40

0 Answers0