Есть ли способ проверить, отменяет ли вызывающий параметр параметр out? - PullRequest
0 голосов
/ 27 августа 2018

Я работаю над библиотекой, и у меня возникают некоторые проблемы с поиском правильного способа придумать правильную структуру API, которая обеспечивает эффективность кода без необходимости иметь кучу различных перегрузок для каждого доступного API.

Скажем, у меня есть этот метод:

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

Теперь я хочу, чтобы пользователь также получил экземпляр EffectAnimation для этих анимаций оттенка и размытия, чтобы он мог анимировать их вбудущее.Предположим, что EffectAnimation это просто delegate, который запускает анимацию для возвращенного Brush.Полный код здесь , на всякий случай.

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.Но это определенно неправильный подход: слишком много беспорядка, и количество API становится слишком большим, если у меня есть, скажем, 3 out параметров.

Итак, мой вопрос: может ли вызывающая сторона проверить, является ли вводout параметр на самом деле является действительной ссылкой, или если использовался идентификатор сброса?Я знаю, что в C # есть множество скрытых трюков и API, есть ли что-то, что могло бы достичь этого?

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Для небольшого числа возможных выходных параметров я бы создал 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 относятся к одному и тому же типу, это не требуется при использовании этого шаблона.

0 голосов
/ 04 сентября 2018

Не совсем то, что вы ищете, но если вы хотите изменить 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'ed

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...