How do I check that a class implements a generic interface in any way?
I have the following:
public class SomeQueryObject : IQueryObject<SomeQueryDto>
{
public SomeQueryDto query { get; set; } = new SomeQueryDto();
}
public class SomeQueryDto : BaseQueryDto
{
// some properties
}
public class BaseQueryDto
{
// some properties
}
public interface IQueryObject<T> where T : BaseQueryDto
{
T query { get; set; }
}
Is there a way to use this interface to check that a parameter implements the generic interface without supplying T? Passing the base class doesn't match, and using the SomeQueryDto class would defeat the point
private static string BuildQueryObjectString<T>(T dto)
where T : IQueryObject<?>
{
//use query field in method body
dto.query= foo;
}
I could change the interface to implement another non generic interface and check that but then classes could just use this and not have the generic interface at all:
public interface IQueryObject<T> : IQueryObject where T : BaseQueryDto
{
T query { get; set; }
}
public interface IQueryObject { }
public class SomeQueryObject : IQueryObject
{
// no query field
}
private static string BuildQueryObjectString<T>(T dto)
where T : IQueryObject // kind of pointless, the above class would pass this check but doesn't implement the field
{
//method body, no access to query field
dto.query= foo; // error
}
Did you want something like this:
public string SomeMethod<T, T1>(T obj) where T : IGenericInterface<T1> where T1 : BaseClass
{
}
but without supplying T1?
You can simplify it depending on you needs: Here is a the full code example of what I think you are trying to achieve. In AnotherClass there are two different method signatures that you can use.
public class BaseClass
{
public virtual string Str { get; set; } = "base";
}
public class DerivedClass : BaseClass
{
public override string Str { get; set; } = "derived";
}
public class TestingClass
{
public TestingClass()
{
AnotherClass a = new AnotherClass();
Console.WriteLine(a.SomeMethod<GenericObjClass<BaseClass>, BaseClass>(new GenericObjClass<BaseClass>(){ Query = new BaseClass()}));
Console.WriteLine(a.SomeMethod<GenericObjClass<DerivedClass>, DerivedClass>(new GenericObjClass<DerivedClass>() { Query = new DerivedClass() }));
Console.WriteLine(a.SomeMethod(new GenericObjClass<BaseClass>() { Query = new BaseClass() }));
Console.WriteLine(a.SomeMethod(new GenericObjClass<BaseClass>() { Query = new DerivedClass() }));
}
}
public class AnotherClass
{
public string SomeMethod<T>(T obj) where T : IGenericObj<BaseClass>
{
return obj.Query.Str;
}
public string SomeMethod<T, T2>(T obj) where T : IGenericObj<T2> where T2 : BaseClass
{
return obj.Query.Str;
}
}
public class GenericObjClass<T> : IGenericObj<T> where T : BaseClass
{
public T Query { get; set; }
}
public interface IGenericObj<T> where T : BaseClass
{
T Query { get; set; }
}