未指定通用属性的比较

22 浏览
0 Comments

未指定通用属性的比较

考虑以下代码:\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 Loader where 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

  1. 我不知道IIdentifiable<>在其泛型括号中有什么,可能是int,string甚至是GUID。\n我尝试了正确的语法typeof(IIdentifiable<>).IsAssignableFrom(typeof(T)),但它总是返回false。\n有没有办法在不知道确切泛型类型的情况下检查T是否是IIdentifiable<>?
  2. \n

  3. 如果有第一个问题的答案,我还想知道如何在不知道它们类型的情况下比较Id字段。\n我发现这个回答非常有用,但它并不适用于我的\n特定情况。
  4. \n

\n我知道如果我将我的Loader类作为两个类型Loader的泛型解决方案,其中K将是\nIIdentifiable<>中的类型,我可能可以解决这个问题,但我想知道是否还有其他解决方案。\n


\n附言:除了我的第一个问题之外:我还好奇为什么可以这样写typeof(IIdentifiable<>).IsAssignableFrom(typeof(T)),如果IIdentifiable<>的泛型类型没有指定,它将返回false?\n


\n编辑:我想,事后看来,我明白为什么不能这样直截了当地写代码-因为可能有集合ICollection,其中条目实现了不同类型的IIdentifiable<>(或根本不实现它),这样的检查会导致尴尬的失败。然而,也许有一种方法可以在某些限制下实现这样的功能,而无需为我的Loader创建第二个泛型参数?

0
0 Comments

问题:Comparison of unspecified generic properties的出现原因以及解决方法

在这里,我们应该分两步来解决你的问题(因为实际上有两个问题需要解决)。

首先,在你的接口`IIdentifiable`中进行以下更改:

public interface IIdentifiable
    where 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();
}

这样更改后,你就可以正确比较未指定的泛型属性了。

0
0 Comments

比较未指定的泛型属性的原因是为了确保正确的类型被使用,并且可以将int和guid转换为字符串。然而,这样做的性能可能会很差,因为实际上需要循环两个容器,时间复杂度为O(n * m)。因此,最好的方法是如果两个源都来自数据库,则适当使用SQL查询,如果在代码中进行操作,则使用字典。此外,如果数据已经被正确排序,可以更高效地找到重复项。

然而,需要注意的是,在C#中泛型的功能是相当有限的。有时候使用`Func<>`可能会有所帮助,但即使这样,仍然需要向算法提供额外的信息。

0
0 Comments

问题的出现原因是作者希望为他的Loader类添加两个方法,但是这些方法需要使用未指定的泛型属性。作者尝试通过CanCast方法来确定T是否可以转换为指定的泛型类型,然后使用Filter方法来过滤数据。然后,在LoadData方法中,根据不同的泛型类型调用不同的方法来处理数据。

然而,作者并不满意这种解决方案,因为他不想引入第二个泛型参数,并且也不想逐个枚举所有可能的情况。

为了解决这个问题,可能有以下几种方法:

1. 引入第二个泛型参数:

- 这是作者当前所采用的解决方案,但他并不满意。

- 通过引入第二个泛型参数,可以使CanCast和Filter方法可以根据不同的泛型类型进行处理。

2. 枚举所有可能的情况:

- 作者表示不想逐个枚举所有可能的情况,但这可能是解决问题的一种方法。

- 可以通过使用条件语句来处理每种可能的泛型类型,然后调用相应的方法。

- 例如,可以使用if语句来处理CanCast()和Filter(),然后再处理CanCast()和Filter(),以此类推。

然而,文章中并没有提供其他解决方案或具体代码,因此无法确定是否还有其他方法来解决这个问题。

0