【问题标题】:C# Generics ProblemC#泛型问题
【发布时间】:2011-01-07 04:28:55
【问题描述】:

我在处理泛型时遇到了问题。

一些背景:

Animal 类是一个泛型类,需要与特定的人相关联

狗是一种只能与Doctor类(Person的子类)相关联的动物

Cat 是一种只能与 Painter 类(Person 的子类)关联的动物

我需要一个方法(名为 SomeMethod)来接收新的动物列表

SomeMethod 将主要处理 Animal 类中的 Owner 属性

using System.Collections.Generic;

namespace Test
{
    class Program
    {
        static void Main()
        {
            SomeMethod(new List<Animal<Person>>(), new List<Dog>());
        }

        public static void SomeMethod<T>(IList<Animal<T>> a, IList<Animal<T>> b)
            where T : Person
        {
            //do something
        }
    }

    class Animal<T>
        where T : Person
    {
        public T Owner { get; set; }
    }

    class Dog : Animal<Doctor>
    {

    }

    class Cat : Animal<Painter>
    {

    }

    class Person
    {

    }

    class Doctor : Person
    {

    }

    class Painter : Person
    {

    }

}

此代码无法编译,因为 SomeMethod() 不接受 2 个不同的列表作为参数。我将使用该方法来比较每个动物的“所有者”属性。有人有想法吗?

【问题讨论】:

  • 解释你想让这个方法做什么——例如,它是不是要根据人的类型过滤动物列表,并且只在合适的时候分配?
  • 您忘记了一个关键细节:问题是什么?
  • 告诉你的老师这是一种非常糟糕的(ab)使用泛型的方法。
  • 我不是真正的学生。上面的代码将在实际项目中使用。当然,它们不是真正的狗和猫,我更改了班级名称。我不确定我是否做出了明智的陈述,因为狗和猫与医生和画家没有真正的关系。无论如何,我们是不是走得太远了?我们应该完全避免使用泛型吗?我真的很想知道
  • 泛型非常适合用于强类型,但仅限于它们有意义的地方。如果您的代码不需要任何强制转换,并且您觉得编译器正在帮助您编写更好的代码,那么您可能使用得很好。但就像 OOP 中的任何事情一样,仅仅因为您可以做某事并不意味着您应该这样做。

标签: generics


【解决方案1】:

您指定的是List&lt;Dog&gt;,其中方法签名需要List&lt;Animal&lt;T&gt;&gt;。该方法可能希望将Cat 添加到您的Dog 列表中。根据方法签名,这应该是合法的,但是您的代码会抛出异常,因为Cat 不是Dog,并且列表专门包含Dog 对象,而不是Animal&lt;T&gt;。因此 C# 编译器将拒绝编译此代码。

所以你有两个选择:

  1. 在 mymethod 中指定 List&lt;Cat&gt;List&lt;Dog&gt;
  2. 创建一个IList&lt;Animal&lt;T&gt;&gt; 并将Dog 对象放入其中以传递给您的方法。

【讨论】:

  • 我可以补充一下,如果你不是特别需要列表函数,你应该传递 IEnumerable 函数。这样您就可以传入 linq 查询,并且可以传入任何动物集合,而不仅仅是可以枚举的列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多