3
public interface ILovable<T> where T : IEquatable<T>
{
    T Care(T t);
}

public class Me : ILovable<int>
{
    public int Care(int i)
    {
        return i;
    }
}

说我有以上。现在下面的功能失败:

private static void Colour<T>(ILovable<T> me) where T : IEquatable<T>
{
    var z = me.Care(1); //cannot convert from 'int' to 'T'
}

上面的代码有什么问题?ILovable<T>有一个Care函数,它吸收 a Twhich is IEquatable<T>。在上面的函数中,我调用了相同的Care函数并传递Tint类型。int毕竟是IEquatable<int>

我究竟做错了什么?有什么办法可以解决吗?

4

5 回答 5

3

您的方法签名没有指定 a ILovable<int>,它指定了ILovable<T>. 例如,这将起作用:

private static void Colour(ILovable<int> me)
{
    var z = me.Care(1); //cannot convert from 'int' to 'T'
}

问题是编译器不知道T在您的示例中这是一个“int”;它可以是任何满足约束的类型。这是另一种可行的方法:

private static void Colour<T>(ILovable<T> me, T valueToCareAbout) where T : IEquatable<T>
{
    var z = me.Care(valueToCareAbout);
}
//use like this
Colour(me, 1);
于 2012-12-29T14:21:14.847 回答
1

我得到的错误是:

Argument type 'int' is not assignable to parameter type 'T'

我很确定这是因为您将其定义meILovable<T>. 因此,它不会自动解析为Meint 定义为的类型T

这将修复错误,因为Me定义Tint

private static void Colour<T>(Me me) where T : IEquatable<T>
        {
            var z = me.Care(1); 
        }
于 2012-12-29T14:20:33.623 回答
1

那是因为方法 Color 说会有 ILovable< T > 类型的参数,而 T 将在稍后解析,所以在编译时我告诉方法 T 是 int 类型。

因此,要么您将 ILovable 作为参数传递,要么将 T 为 int 的被授予者

void Colour<T>(ILovable<int> me)

或者直接通过 type Me

void Colour<T>(Me me)

因为否则 me.Care 期望类型 T 而不是 int 作为特定

于 2012-12-29T14:25:24.633 回答
1

更改以下

private static void Colour<T>(ILovable<T> me) where T : IEquatable<T>

private static void Colour<Int32>(ILovable<int> me) 

及以上将工作。


现在是神秘部分

您在关注时遇到错误

private static void Colour<T>(ILovable<T> me) where T : IEquatable<T>

因为Care是 期待T, 而 你 是 提供int.
它与

Care((T)1).

或者

 T t = (T)1; //This is the cause of error as int cannot be changed to T. Remember Int32 is sealed so T cannot derive from int

 Care(t); // This is fine

要进行上述工作,T必须int. 为此,Colur 方法语法应该像

   private static void Colour<Int32>(ILovable<int> me) 

如果你想将字符串传递给CareT应该是string

  private static void Colour<string>(ILovable<string> me) 
  {
     me.Care("Hello");
  }

Colour现在,如果我们必须修复 T,那么问题就出现了,为什么在定义中根本需要 T。

答案-> 对于非密封类中的不处理继承类型。

于 2012-12-29T17:37:02.727 回答
0

简短的回答是在泛型方法(或类)中用更派生的类型覆盖类型的变量T是不可能的,因为编译器没有明确知道T更多派生类型(在我们的例子T中是int),因为T可以是任何其他派生的在运行时键入。

长答案:me变量是类型ILovable<T>。现在me.Care函数需要指定类型的参数ILovable<T>TCare函数之外T可以是任何东西IEquatable<T>,所以int没关系。但在函数内部,T必须是 justT而不是另一个派生类型IEquatable<T>. 否则这样的场景会出现运行时错误:

private static void Colour<T>(ILovable<T> me) where T : IEquatable<T>
{
    var z = me.Care(1); 
}

...

Colour("");

现在,T调用时是字符串Colour("")me也是如此ILovable<string>。所以me.Care函数需要一个string作为参数,但提供的是一个int,那就是灾难。

于 2012-12-31T02:47:51.897 回答