【发布时间】:2017-07-25 10:05:03
【问题描述】:
考虑以下代码:
public interface IIdentifiable<T>
{
T Id { get; set; }
}
public interface IViewModel
{
}
public class MyViewModel1 : IViewModel, IIdentifiable<int>
{
public string MyProperty { get; set; }
public int Id { get; set; }
}
public class MyViewModel2 : IViewModel, IIdentifiable<string>
{
public string MyProperty { get; set; }
public string Id { get; set; }
}
我也有使用 ViewModels 的类:
public class Loader<T> where T: IViewModel
{
public void LoadData()
{
/*some important stuff here*/
if (typeof(IIdentifiable<??>).IsAssignableFrom(typeof(T)))
{ // ^- here's the first problem
data = data.Where(d => _dataSource.All(ds => ((IIdentifiable<??>) ds).Id != ((IIdentifiable<??>) d).Id)).ToList();
} // ^---- and there the second ----^
/*some important stuff here too*/
}
}
现在,如您所见,我拥有的视图模型可能会实现 IIdentifiable<> 接口。我想检查一下,如果是真的,
我想确保我的data 列表不包含我的_dataSourse 列表中已经存在的任何条目。
所以我有两个问题:
我不知道
IIdentifiable<>的通用括号里有什么,可能是int、string甚至GUID。 我试过typeof(IIdentifiable<>).IsAssignableFrom(typeof(T)),这是正确的语法,但它总是返回false。 有没有办法在不知道确切泛型类型的情况下检查T是否为IIdentifiable<>?如果第一个问题有答案,我也想知道如何在不知道它们类型的情况下比较
Id字段。 我发现this answer 非常有用,但它并没有涵盖我的 具体情况。
我知道如果我将Loader<T> 类设为两种类型Loader<T,K> 的泛型,我可能可以解决这个问题,其中K 将是
输入IIdentifiable<>,但我想知道是否有其他解决方案。
附:除了我的第一个问题:我也很好奇,如果没有指定IIdentifiable<> 的泛型类型时返回false,为什么可以写类似typeof(IIdentifiable<>).IsAssignableFrom(typeof(T)) 的东西?
编辑:我想,事后看来,我明白为什么我不能直截了当地写代码——因为可能有集合ICollection<IViewModel>,其中的条目实现了不同类型的IIdentifiable<> (或者根本不实现它),这样的检查会尴尬地失败。然而,也许有一种方法可以在有一些限制的情况下执行类似的操作,但无需为我的Loader 创建第二个通用参数?
【问题讨论】:
-
我不确定你想要达到什么目标,但如果你的 IIdentifiable
实现 IComparable 可能会有所帮助