我有以下通用类:
public class SearchResult<T>
{
public int ResultCount { get; set; }
public IEnumerable<T> Result { get; set; }
}
我还有一个Bird
类,它实现了IFlyble
接口:
public class Bird : IFlyable
{
public void Fly() {}
}
public interface IFlyable
{
void Fly();
}
我还有res
类型的变量object
。
如何检查res
是否为SearchResult<IFlyable>
?
我试着这样做:
if (res.GetType().IsAssignableFrom(typeof(SearchResult<IFlyable>)))
{
///
}
就这样:
if(res is SearchResult<IFlyable>)
{
///
}
但它似乎不起作用。
答案 0 :(得分:15)
您遇到的问题可能是由于SearchResult<Bird>
无法转换到SearchResult<IFlyable>
,因为SearchResult<T>
在T
中不变
C#只承认接口和委托中的泛型类型差异。您需要定义一个ISearchResult<>
接口,该接口在其泛型类型中是协变的。
在您的情况下,如果可以接受T
仅用作输出,您可以按如下方式定义此类界面:
public interface ISearchResult<out T>
{
int ResultCount { get; }
IEnumerable<T> Result { get; }
}
现在ISearchResult<Bird>
是ISearchResult<IFlyable>
,因为您已经为编译器提供了足够的信息,以便它可以验证转换实际上是安全的
答案 1 :(得分:1)
你也可以尝试使用反射,它也可以工作,不需要创建另一个界面。
static void Main()
{
var sr = new SearchResult<Bird>();
Console.WriteLine(IsSearchResultIFlyable(sr.GetType())
? "sr is SearchResult<IFlyable>"
: "sr is Not SearchResult<IFlyable>");
Console.ReadLine();
}
public static bool IsSearchResultIFlyable(Type t)
{
if (!t.IsGenericType) return false;
if (t.GetGenericTypeDefinition() != typeof(SearchResult<>)) return false;
var gr = t.GetGenericArguments();
return gr.Length == 1 && typeof(IFlyable).IsAssignableFrom(gr[0]);
}