有没有办法检查调用者是否有out参数?

问题描述 投票:2回答:2

我正在开发一个库,我在寻找正确的API结构方面遇到了一些麻烦,这种API结构使代码保持高效,而不需要为每个可用的API提供大量不同的重载。

说我有这个方法:

public static Brush CreateDummyBrush(Color tint, float mix, float blur)

现在,我想让用户同时收到一个EffectAnimation实例,用于那些色调和模糊动画,让他在将来为它们设置动画。假设EffectAnimation只是一个delegate,它在返回的Brush上开始动画。完整的代码是here,以防万一。

public static Brush CreateDummyBrush(
    Color tint, float mix, out EffectAnimation mixAnimation,
    float blur, out EffectAnimation blurAnimation)

现在,如果用户想要为这两个动画接收delegate,这是完全正常的。但是,假设我只需要设置模糊效果的动画,那么我就像这样调用这个API:

Brush brush = CreateDummyBrush(Colors.Gray, 0.6f, out _, 8, out var blurAnimation);

这是有效的,但是库最终会分配一个无用的delegate,因为它只是被丢弃了。

快速解决方案是创建4个不同的重载,以涵盖out参数的各种组合。但绝对不是正确的方法:太杂乱,如果我有3个out参数,API的数量会变得太大。

所以我的问题是:调用者可以检查输入out参数是否实际上是一个有效的引用,或者是否已使用丢弃标识符?我知道C#有很多隐藏的技巧和API,有什么东西可以实现这个目标吗?

非常感谢!

c# .net c#-7.0
2个回答
0
投票

不完全是你想要的,但如果你想改变API以返回一个元组...

public (Brush, EffectAnimation, EffectAnimation)  CreateDummyBrush(Color tint, float mix, float blur)
{
enter code here
}

//call it like so
var (brush, _, _) = CreateDummyBrush( tint, mix, blur);
var (brush, mixAnimation, _) = CreateDummyBrush( tint, mix, blur);

它不会保存函数内的处理来创建对象,但至少它们将是GC


0
投票

对于少量可能的输出参数,我创建了一个Enum和一个struct

[Flags]
public enum RequestedEffect {
    None = 0,
    Mix = 1,
    Blur = 2,
    DanceLightFandango = 4
}

public struct Effects {
    public RequestedEffect Effect;
    public EffectAnimation BlurEffect;
    public EffectAnimation MixEffect;
    public EffectAnimation DanceLightFanangoEffect;
}

然后,您将更改签名为:

public static Brush CreateDummyBrush(
Color tint, float mix, float blur,
ref Effects animations){...}

然后,如果对此结构进行任何初始化,则由调用者决定 - default(Effect)意味着调用者不请求任何动画。您可能希望更改一些命名。


请注意,虽然在上面,Effects中的所有非枚举字段都是相同的类型,但在使用此模式时不需要。

© www.soinside.com 2019 - 2024. All rights reserved.