2017-04-21 116 views
2

如何檢查某個類以任何方式實現通用接口?C#檢查通用接口的實現

我有以下幾點:

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上的通用接口的方法嗎? 傳遞基類的不匹配,並使用SomeQueryDto類會破壞點

private static string BuildQueryObjectString<T>(T dto) 
     where T : IQueryObject<?> 
{ 
    //use query field in method body 
    dto.query= foo; 
} 

我可以改變的接口來實現另一個非通用接口,並檢查,但隨後類可以只使用這個,而不是具有通用接口都:

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 
} 
+0

什麼是IUDGroupQueryObject? – Scrobi

+0

我的不好,我是爲了清晰而重新命名的東西,並錯過了 – lanky393

回答

1

你有沒有想是這樣的:

​​

,但沒有提供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; } 
} 
+0

是的,這就是我想要的,說實話,我會解決通過這兩個,就像你建議的,只是認爲它可能更整潔:) – lanky393

0

如果我理解正確的,你,你要做的是檢查類實現特別泛型類型通用接口。假設你有一個類的實例,你可以做,在這種方式:

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 
    } 
} 

另外,如果您有任何情況,並希望使類檢查,只需用typeof(SomeDto)取代instnace.GetType()

+0

我不想檢查,我想有一個方法簽名,可以採取任何類型的ISome <>。 謝謝 – lanky393

+0

所以我們來清除它:你有一個實現了'ISome '的類,並且想要在其中接受一個類型爲'ISome '的參數的方法? – Seprum