C# 检查泛型接口的实现
C# Check for implementation of generic interface
如何检查 class 是否以任何方式实现通用接口?
我有以下内容:
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; }
}
有没有办法在不提供 T 的情况下使用此接口来检查参数是否实现通用接口?
传递基数 class 不匹配,使用 SomeQueryDto class 会破坏点
private static string BuildQueryObjectString<T>(T dto)
where T : IQueryObject<?>
{
//use query field in method body
dto.query= foo;
}
我可以更改接口以实现另一个非通用接口并检查,但是 classes 可以只使用它而根本没有通用接口:
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
}
如果我没理解错的话,你想做的是检查 class 是否实现了具有特定泛型类型的泛型接口。假设你有一个 class 的实例,你可以通过这种方式做到这一点:
class Dto
{
// definition
}
interface ISome<T>
{
// definition
}
class SomeDto: ISome<Dto>
{
// definition
}
...
var instance = new SomeDto();
foreach(var type in instance.GetType().GetInterfaces()) {
if(type.IsGenericType
&& type.GetGenericTypeDefinition() == typeof(ISome<>)
&& type.GetGenericArguments()[0] == typeof(Dto)) {
// success
}
}
此外,如果您没有实例并想进行 class 检查,只需将 instnace.GetType()
替换为 typeof(SomeDto)
。
你想要这样的东西吗:
public string SomeMethod<T, T1>(T obj) where T : IGenericInterface<T1> where T1 : BaseClass
{
}
但没有提供 T1?
您可以根据需要对其进行简化:这是我认为您正在尝试实现的完整代码示例。在 AnotherClass 中,您可以使用两种不同的方法签名。
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; }
}
如何检查 class 是否以任何方式实现通用接口?
我有以下内容:
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; }
}
有没有办法在不提供 T 的情况下使用此接口来检查参数是否实现通用接口? 传递基数 class 不匹配,使用 SomeQueryDto class 会破坏点
private static string BuildQueryObjectString<T>(T dto)
where T : IQueryObject<?>
{
//use query field in method body
dto.query= foo;
}
我可以更改接口以实现另一个非通用接口并检查,但是 classes 可以只使用它而根本没有通用接口:
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
}
如果我没理解错的话,你想做的是检查 class 是否实现了具有特定泛型类型的泛型接口。假设你有一个 class 的实例,你可以通过这种方式做到这一点:
class Dto
{
// definition
}
interface ISome<T>
{
// definition
}
class SomeDto: ISome<Dto>
{
// definition
}
...
var instance = new SomeDto();
foreach(var type in instance.GetType().GetInterfaces()) {
if(type.IsGenericType
&& type.GetGenericTypeDefinition() == typeof(ISome<>)
&& type.GetGenericArguments()[0] == typeof(Dto)) {
// success
}
}
此外,如果您没有实例并想进行 class 检查,只需将 instnace.GetType()
替换为 typeof(SomeDto)
。
你想要这样的东西吗:
public string SomeMethod<T, T1>(T obj) where T : IGenericInterface<T1> where T1 : BaseClass
{
}
但没有提供 T1?
您可以根据需要对其进行简化:这是我认为您正在尝试实现的完整代码示例。在 AnotherClass 中,您可以使用两种不同的方法签名。
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; }
}