Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

suspicious cast there is no type in the solution which is inherited from both

I should cast one class into Generic Interface because of some requirements. But I am having ReSharper warning "suspicious cast there is no type in the solution which is inherited from both". In run time, it cause run time error.

I should do this because I am using reflection so I desperetly need this cast. My code as below. Any support appreceated.

    class Program
{
    static void Main(string[] args)
    {
        // prepare class name from string
        string propertyNavigationFullName = "ConsoleApp1.Entry";

        // Take assembly
        Assembly assem = typeof(Entry).Assembly;

        // take class type
        Type className = assem.GetType(propertyNavigationFullName, true);

        // create class instance
        IEntitySubMultiLang inst = (IEntitySubMultiLang)Activator.CreateInstance(className);

        // prepare Generic Class
        Type genericClass = typeof(GenericRepo<>);
        Type constructedClass = genericClass.MakeGenericType(className);

        // create Generic Class instance
        // ERROR OCCUR HERE
        IRepo<IEntitySubMultiLang> created = (IRepo<IEntitySubMultiLang>)Activator.CreateInstance(constructedClass);

        // I need to use Add method or any other method
        created.Add(inst);

    }

    public interface IEntitySubMultiLang
    {
        int Id { get; set; }
    }

    public interface IRepo<TEntity> where TEntity : class, IEntitySubMultiLang
    {
        void Add(TEntity item);
    }

    public class GenericRepo<TEntity> : IRepo<TEntity> where TEntity : class, IEntitySubMultiLang
    {
        public void Add(TEntity item)
        {

        }
    }

    public class Entry : IEntitySubMultiLang
    {
        public int Id { get; set; }
    }
}

ScreenShot

like image 638
Savas Karaduman Avatar asked Nov 28 '25 23:11

Savas Karaduman


1 Answers

If you think about what this means, the cast you're talking about is actually incorrect, which is why it doesn't work. Suppose you have another class that implements IEntitySubMultiLang:

public class Foo : IEntitySubMultiLang
{
    public int Id { get; set; }
}

What would happen if you passed a Foo to _r.Add()?

_r.Add(new Foo());

This wouldn't make any sense, because _r is a GenericRepo<Entry>, and doesn't know how to add Foos. That's exactly the sort of situation type safety is supposed to avoid.

Update, based on OP Edit

Because you're using reflection to produce your objects, you're really getting no compile-time benefit from the interfaces in terms of type safety when you're calling _r.Add(). So embrace that fact, and use reflection to call the Add method, without attempting to do any casting.

    constructedClass
        .GetMethod("Add")
        .MakeGenericMethod(className)
        .Invoke(created, new object[] { inst });

Alternatively, there is a good chance you can simplify a lot of your code, and still get a lot of type safety, by putting everything into a generic helper method, and calling that method by reflection. For example:

static private void AddToRepo<TEntity>() where TEntity : class, IEntitySubMultiLang, new
{
    new GenericRepo<TEntity>().Add(new TEntity());
}
    typeof(ConsoleApp1)
        .GetMethod("AddToRepo")
        .MakeGenericMethod(className)
        .Invoke(null, new object[] { /* any parameters? */});

like image 73
StriplingWarrior Avatar answered Nov 30 '25 13:11

StriplingWarrior



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!