【问题标题】:C# generics: using class generic in where clause of method genericC# 泛型:在方法泛型的 where 子句中使用类泛型
【发布时间】:2012-06-04 17:10:59
【问题描述】:

谁能解释为什么这不可能(至少在 .Net 2.0 中):

public class A<T>
{
    public void Method<U>() where U : T
    {
        ...
    }
}

...

A<K> obj = new A<K>();
obj.Method<J>();

K 是 J 的超类

编辑

我试图简化问题以使问题更清晰易读,但我显然做得过火了。对不起!

我想我的问题更具体一点。这是我的代码(基于this):

public class Container<T>
{
    private static class PerType<U> where U : T
    {
        public static U item;
    }

    public U Get<U>() where U : T
    {
        return PerType<U>.item;
    }

    public void Set<U>(U newItem) where U : T
    {
        PerType<U>.item = newItem;
    }
}

我收到了这个错误:

Container.cs(13,24):错误 CS0305:使用泛型类型 Container&lt;T&gt;.PerType&lt;U&gt;' requires2' 类型参数

【问题讨论】:

  • 在 4.0 中是可能的。不是很有用,因为你没有在签名中使用类型参数,但绝对可以。
  • 它确实有效,即使在 .NET 2.0 中也是如此。
  • 你说得对,我已经编辑了这个问题。对不起。
  • 即使经过编辑,代码也能正常工作。
  • 好吧,我肯定得到了上面的错误。这发生在使用 Mono 编译器的 Unity 内部。不知道有没有关系。

标签: c# generics .net-2.0


【解决方案1】:

其实是可以的。这段代码编译并运行得很好:

public class A<T>
{
    public void Act<U>() where U : T
    {
        Console.Write("a");
    }
}

static void Main(string[] args)
{
  A<IEnumerable> a = new A<IEnumerable>();
  a.Act<List<int>>();
}

正如here 解释的那样,在泛型中使用协变/逆变是不可能的:

IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;

【讨论】:

  • 仍然可以编译并工作(当然 U Item 将始终保持为空 - 您没有提供初始化 PertTyp 类/它的 item 字段的方法)
  • 请查看我对我的问题的最新评论。初始化应该通过调用 Set 方法来完成。 obj.Set(jObj) PerType 类应该是静态的。我在调试时将其删除。我已编辑问题以再次添加关键字。
  • 它仍然有效.. 也许你应该提供你的完整代码?
  • 这是我的全部代码。真的没有什么了。我已经用这个类开始了一个新的 Unity 项目,它给出了同样的错误。也许这是 Mono 或 Unity 特定的错误。我会尝试在其他平台上测试它。感谢您的帮助。
  • 看来最终可以和Unity中的Mono编译器相关。 answers.unity3d.com/questions/262475/… 明天我会尝试进一步证实这个假设。感谢您的帮助。
【解决方案2】:

它对我有用(VS 2008)。

您对课程可见性有疑问吗? (类不公开,命名空间错误)

您收到哪条错误消息?


更新

鉴于您对Container&lt;T&gt; 的实现,我可以写

class A { }
class B : A { }

class Test
{
    public void MethodName( )
    {
        var obj = new Container<A>();
        obj.Set(new B());
    }
}

这非常有效。你确定B 派生自A 吗?请注意,例如 List&lt;B&gt; 不是从 List&lt;A&gt; 派生的(请参阅 YavgenyP 的答案)。


错误消息可能是一个提示,告诉您在另一个命名空间中存在另一个 Container&lt;T&gt;,需要 PerType&lt;U, X??? &gt; 的第二个类型参数。

【讨论】:

  • 这应该是评论而不是答案。
  • 这可能是 Mono 编译器或 Unity 的错误。我在他们的问答系统中问过同样的问题。目前我无法对此进行测试(明天我将在办公室检查),但编译器似乎有问题:answers.unity3d.com/questions/262475/… 不过感谢您的洞察力。
  • 我刚刚确认过了。添加“容器”。前缀解决了这个问题。它应该是由 Mono C# 编译器中的一些错误引起的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-16
相关资源
最近更新 更多