Action <t>参数</t>的通用方法

时间:2009-11-24 18:48:14

标签: c# generics delegates

所以,我确信之前已在某处回答过,但我无法在任何地方找到它。希望一些仿制药专家可以提供帮助。

public interface IAnimal{}
public class Orangutan:IAnimal{}

public void ValidateUsing<T>(Action<T> action) where T : IAnimal
{
    Orangutan orangutan = new Orangutan();
    action(orangutan);  //Compile error 1

    //This doesn't work either:
    IAnimal animal = new Orangutan();
    action(animal);  //Compile error 2
}
  1. 参数类型'T'
  2. 不能赋予参数类型'Orangutan'
  3. 参数类型'Tnimal'不能分配给参数类型'T'
  4. 编辑:根据Yuriy和其他人的建议,我可以做一些演员如:

    public void ValidateUsing<T>(Action<T> action) where T : IAnimal
    {
        Orangutan orangutan = new Orangutan();
        action((T)(IAnimal)orangutan);
    
        //This doesn't work either:
        IAnimal animal = new Orangutan();
        action((T)animal);
    }
    

    我想要做的是调用ValidateUsing方法,如下所示:

    ValidateUsing(Foo);  
    

    不幸的是,如果foo看起来像这样:

    private void Foo(Orangutan obj)
    {
        //Do something
    }
    

    当我调用ValidateUsing

    时,我必须明确指定类型
    ValidateUsing<Orangutan>(Foo);
    

5 个答案:

答案 0 :(得分:6)

如果您应该接受任何Orangutan,为什么要实例化IAnimal

public void ValidateUsing<T>(Action<T> action) where T : IAnimal, new()
{
    T animal = new T();
    action(animal);  //Compile error 2

如果您重复使用通用参数,则不会出现任何类型问题......

现在,关于您的代码无效的原因,您所说的只是T类型派生自IAnimal。但是,GiraffeOrangutan一样容易,因此您不能只将OrangutanIAnimal分配给T类型的参数}。

答案 1 :(得分:4)

问题是,T代表某种类型,它实现了IAnimal。

因此,当您尝试编译action(new Organatum())时,您会收到错误,因为您已声明该操作应采用T类型的参数,而该参数又可以是类型,例如,{ {1}} - 您无法将Fish投射到Organatum,是吗?

如果要触发任何采用实现Fish接口的类型参数的操作,那么只需忘记泛型并使用IAnimal

HTH。

答案 2 :(得分:2)

试试这个。

Orangutan orangutan = new Orangutan();
Action<IAnimal> castedAction = action as Action<IAnimal>;
castedAction(orangutan);

答案 3 :(得分:2)

进行以下更改:

Orangutan orangutan = new Orangutan();
action((T)(IAnimal)orangutan); 


IAnimal animal = new Orangutan();
action((T)animal); 

答案 4 :(得分:0)

public interface IAnimal { }
public class Orangutan : IAnimal { }

public void ValidateUsing<T>(Action<T> action) where T : IAnimal
{
    Orangutan orangutan = new Orangutan();
    action((T)(orangutan as IAnimal));  // needs to be cast as IAnimal

    //This doesn't work either:
    IAnimal animal = new Orangutan();
    action((T)animal);  // needs to be cast as T
}

看起来这也是一个界面有所作为的事实。如果你有一个抽象类Animal,而不是一个接口,你可以这样做:

public abstract class Animal { }
public class Orangutan : Animal { }

public void ValidateUsing<T>(Action<T> action) where T : Animal
{
    Orangutan orangutan = new Orangutan();
    action(orangutan as T); 

    //This doesn't work either:
    Animal animal = new Orangutan();
    action(animal as T); 
}