如何从lambda表达式构造Action <t>?

时间:2018-10-26 22:41:47

标签: c#

我有此代码:

public static Tween.TweenExecuter To<T>(ref this T thisArg, T to, float time, EasingType easing = EasingType.Linear,
    TweenType type = TweenType.Simple, Func<bool> trigger = null, Action callback = null) where T : struct
{
    Tween.TweenElement<T> tween = new Tween.TweenElement<T>() 
        {
            from = thisArg,
            Setter = x => thisArg = x,
            to = to,
            time = time,
            easing = easing,
            type = type,
            Trigger = trigger,
            Callback = callback
        };

        tween = t;


    return new Tween.TweenExecuter(tween);
}

应该将设置程序分配给Action<T>,但编译器会抱怨:错误CS1628:无法在匿名方法,lambda表达式或查询表达式中使用ref或out参数'thisArg'

否则如何使用Action<T>

编辑:

这是类型声明:

public abstract class BaseTween
{
    public float time;
    public float currentTime;
    public EasingType easing;
    public TweenType type;
    public bool deleteAtEnd = false;
    public Func<bool> Trigger;
    public Action Callback;
}

public class TweenElement<T> :BaseTween
{
    public Action<T> Setter;
    public T from;
    public T to;

}

1 个答案:

答案 0 :(得分:0)

您可以删除ref关键字,并将其替换为其他形式的间接寻址,例如容器类。在此示例中,我创建了一个名为Ref的容器类,该容器类专门用于保存另一个值。

class Ref<T>
{
    public T Value { get; set; }

    public Ref(T item)
    {
        Value = item;
    }

    public override string ToString()
    {
        return Value.ToString();
    }

    public static implicit operator T(Ref<T> source)
    {
        return source.Value;
    }
}

我仍然不能再通过引用传递任何内容,但是如果传递Ref对象,则该方法可以更新其属性。

public class Program
{
    static Ref<Foo> _container = new Ref<Foo>(null);

    static void MyMethod(Ref<Foo> thisArg) 
    {
        Action action = () => thisArg.Value = new Foo("After");
        action();
    }

    public static void Main()
    {
        _container.Value = new Foo("Before");
        Console.WriteLine("Value before  call is: {0}", _container);
        MyMethod(_container);
        Console.WriteLine("Value after call is: {0}", _container);
    }
}

输出:

Value before call is: Before
Value after call is: After

请参见DotNetFiddle上的有效示例。

编辑:要将解决方案放入您的代码中,如下所示:

public static Tween.TweenExecuter To<T>(this Ref<T> thisArg, T to, float time, EasingType easing = EasingType.Linear, TweenType type = TweenType.Simple, Func<bool> trigger = null, Action callback = null) where T : struct
{
    Tween.TweenElement<T> tween = new Tween.TweenElement<T>() 
    {
        from = thisArg,
        Setter = x => thisArg.Value = x,
        to = to,
        time = time,
        easing = easing,
        type = type,
        Trigger = trigger,
        Callback = callback
    };

    return new Tween.TweenExecuter(tween);
}