未指定通用属性的比较
未指定通用属性的比较
考虑以下代码:\n
public interface IIdentifiable{ T Id { get; set; } } public interface IViewModel { } public class MyViewModel1 : IViewModel, IIdentifiable { public string MyProperty { get; set; } public int Id { get; set; } } public class MyViewModel2 : IViewModel, IIdentifiable { public string MyProperty { get; set; } public string Id { get; set; } }
\n我还有一个与ViewModels操作的类:\n
public class Loaderwhere T: IViewModel { public void LoadData() { /*一些重要的代码*/ if (typeof(IIdentifiable?>).IsAssignableFrom(typeof(T))) { // ^- 这里是第一个问题 data = data.Where(d => _dataSource.All(ds => ((IIdentifiable?>) ds).Id != ((IIdentifiable?>) d).Id)).ToList(); } // ^---- 这里是第二个问题 ----^ /*一些其他重要的代码*/ } }
\n现在,正如您所看到的,我拥有的viewmodels可能实现了IIdentifiable<>接口。我想检查一下,如果是真的,\n我想确保我的data列表中不包含任何已经存在于我的_dataSourse列表中的条目。\n所以我有两个问题:\n
- \n
- 我不知道IIdentifiable<>在其泛型括号中有什么,可能是int,string甚至是GUID。\n我尝试了正确的语法
typeof(IIdentifiable<>).IsAssignableFrom(typeof(T))
,但它总是返回false。\n有没有办法在不知道确切泛型类型的情况下检查T是否是IIdentifiable<>? - 如果有第一个问题的答案,我还想知道如何在不知道它们类型的情况下比较Id字段。\n我发现这个回答非常有用,但它并不适用于我的\n特定情况。
\n
\n
\n我知道如果我将我的Loader
\n附言:除了我的第一个问题之外:我还好奇为什么可以这样写typeof(IIdentifiable<>).IsAssignableFrom(typeof(T))
,如果IIdentifiable<>的泛型类型没有指定,它将返回false?\n
\n编辑:我想,事后看来,我明白为什么不能这样直截了当地写代码-因为可能有集合ICollection
,其中条目实现了不同类型的IIdentifiable<>
(或根本不实现它),这样的检查会导致尴尬的失败。然而,也许有一种方法可以在某些限制下实现这样的功能,而无需为我的Loader
创建第二个泛型参数?
问题:Comparison of unspecified generic properties的出现原因以及解决方法
在这里,我们应该分两步来解决你的问题(因为实际上有两个问题需要解决)。
首先,在你的接口`IIdentifiable
public interface IIdentifiablewhere T : IEquatable { T Id { get; set; } }
这将确保你可以正确比较`Id`属性。
其次,在你的`LoadData()`方法中,将`if`语句更改为:
if (T is IIdentifiable) { // ^- 这是第一个问题 data = data.Where(d => _dataSource.All(ds => ((IIdentifiable ) ds).Id != ((IIdentifiable ) d).Id)).ToList(); }
这样更改后,你就可以正确比较未指定的泛型属性了。
问题的出现原因是作者希望为他的Loader
然而,作者并不满意这种解决方案,因为他不想引入第二个泛型参数,并且也不想逐个枚举所有可能的情况。
为了解决这个问题,可能有以下几种方法:
1. 引入第二个泛型参数:
- 这是作者当前所采用的解决方案,但他并不满意。
- 通过引入第二个泛型参数,可以使CanCast和Filter方法可以根据不同的泛型类型进行处理。
2. 枚举所有可能的情况:
- 作者表示不想逐个枚举所有可能的情况,但这可能是解决问题的一种方法。
- 可以通过使用条件语句来处理每种可能的泛型类型,然后调用相应的方法。
- 例如,可以使用if语句来处理CanCast
然而,文章中并没有提供其他解决方案或具体代码,因此无法确定是否还有其他方法来解决这个问题。