限制较少或同等派生类型的参数

时间:2017-06-01 05:21:48

标签: c#

我有一个“转移”方法,旨在从一堆到另一堆。现在显然你不想将东西转移到错误类型的堆中。

EventFiringWebDriver eventFiringWebDriver = new EventFiringWebDriver(driver);
    MyWebDriverListerner handler = new MyWebDriverListerner();
    eventFiringWebDriver.register(handler);

我想以这样的方式设置我的通用参数,即“桩”不能转移到“肉”。类型T由参数定义,当一个从另一个派生时,它采用最少的派生。我想强制它采取第一个参数,如果第二个参数无效,则给出编译器错误。

我能想到的一个解决方案就是这个,但看起来有点粗糙。 (尚未测试过)我更喜欢编译器错误而不是运行时异常。

using System.Collections;

public class Pile
{
    public int Amount;

    public int GetAmount { get { return Amount; } }
}

public static class PileHelper
{
    public static void Transfer<T>(this T from, T to, int amount) where T : Pile
    {
        from.Amount -= amount;
        to.Amount += amount;
        //Debug.Log(amount + " " + typeof(T).ToString() + " sent.");
    }
}

//example
public class Meat : Pile
{
}

public class Fruit : Pile
{
}

public class Example
{
    public void Test()
    {
        var meat = new Meat();
        var fruit = new Fruit();
        var pile = new Pile();

        meat.Transfer(pile, 1); //correctly compiles, can transfer to a less derived type
        meat.Transfer(fruit,1); //correctly does not compile, different types
        pile.Transfer(meat, 1); //incorrectly compiles, should not compile because transfering to a more derived type
    }
}

我将不得不遗憾地排除协方差和逆变,因为Unity3D在使用时会出现各种运行时错误。它是关于传递复杂指针的已知问题。

2 个答案:

答案 0 :(得分:3)

您需要具有2个参数的通用来设置它们之间的关系。我认为你正在寻找从第二类派生(或等于)作为限制的第一个参数的类:

public static void Transfer<T,Y>(this T from, Y to, int amount) 
   where T : Y     // T is same or derived from Y
   where Y : Pile  // Y is Pile, hence T is Pile too.
{
    from.Amount -= amount;
    to.Amount += amount;
    //Debug.Log(amount + " " + typeof(T).ToString() + " sent.");
}

这两种情况都失败了。

答案 1 :(得分:-1)

您也可以尝试Reflection as describe in the answers here但最终您必须抛出(自定义)异常并让调用者处理这种情况 - 毕竟它是一个公共API。