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
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.
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? */});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With