Skip to content

Modernize the bool + out-param return pattern across the public API #2029

Description

@shimat

Summary

Several public API methods use the C-style pattern bool MethodName(..., out T result, ...), where the bool return indicates success/failure and the actual result comes back via an out parameter. This came up during review of the imgcodecs #2009 coverage work (Cv2.ImReadMulti, Cv2.ImDecodeMulti, etc.) and is worth addressing more broadly rather than one-off per method.

Rough scope (~22 methods across 12 files, from a quick survey):

File Count Examples
Cv2_imgcodecs.cs 8 ImReadMulti, ImDecodeMulti, ImEncode (x2), ImEncodeAnimation, ImEncodeWithMetadata, ImEncodeMulti
Modules/objdetect/QRCodeDetector.cs 4 Detect, DetectMulti, DecodeMulti (x2)
Cv2_calib.cs 2 FindChessboardCorners, FindCirclesGrid (out overloads)
Cv2_core.cs 1 CheckRange
Cv2_stereo.cs 1 StereoRectifyUncalibrated
Cv2_objdetect.cs 1 FindChessboardCornersSB (out overload)
Modules/videoio/VideoCapture.cs 1 WaitAny
Modules/aruco/Dictionary.cs 1 Identify
Modules/imgproc/FontFace.cs 1 GetInstance
Modules/saliency/ObjectnessBING.cs 1 ComputeSaliency
Modules/face/Facemark/Facemark.cs 1 Fit

No method in the public API is currently named TryXxx (the only TryGetValue-style member is MatOfT<T>.TryGetValue, which already follows the idiomatic try-pattern). So there's no existing convention to extend here — this issue would be establishing one.

Problem

  • The shape itself is dated versus idiomatic modern C# (throw-on-failure, return a default/empty value on failure, or an explicitly-named TryXxx method).
  • Argument validation is inconsistent across methods that otherwise look similar. For example, in Cv2_imgcodecs.cs, ImReadMulti/ImReadWithMetadata/ImReadAnimation only null-check the filename (ArgumentNullException.ThrowIfNull), while ImRead/ImWrite/ImEncode reject empty strings too (string.IsNullOrEmpty) — so Cv2.ImReadMulti("", out mats) silently returns false where Cv2.ImRead("") throws.

Proposal (needs discussion, not decided yet)

Options to consider per method/family:

  1. Return T directly, with an empty/default value signaling failure (matches Mat's existing "return empty Mat on failure" convention used by ImRead/ImDecode).
  2. Keep the bool-return shape but rename to TryXxx to make the contract explicit (matches BCL convention, e.g. int.TryParse).
  3. Throw on failure instead of returning a sentinel/bool (bigger behavior change, more invasive at call sites).

Given OpenCvSharp5 is a major-version line where breaking API changes are acceptable, any of the above is on the table. This issue is to track the discussion and decide a consistent policy before touching all ~22 methods.

Scope note

The imgcodecs null/empty-check inconsistency mentioned above is being fixed narrowly (just the check, not the out+bool shape itself) as part of the #2009 imgcodecs coverage PR. This issue is about the broader shape decision across the whole public API, which is intentionally kept out of that PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions