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:
- Return
T directly, with an empty/default value signaling failure (matches Mat's existing "return empty Mat on failure" convention used by ImRead/ImDecode).
- Keep the bool-return shape but rename to
TryXxx to make the contract explicit (matches BCL convention, e.g. int.TryParse).
- 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.
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 anoutparameter. 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):
Cv2_imgcodecs.csImReadMulti,ImDecodeMulti,ImEncode(x2),ImEncodeAnimation,ImEncodeWithMetadata,ImEncodeMultiModules/objdetect/QRCodeDetector.csDetect,DetectMulti,DecodeMulti(x2)Cv2_calib.csFindChessboardCorners,FindCirclesGrid(out overloads)Cv2_core.csCheckRangeCv2_stereo.csStereoRectifyUncalibratedCv2_objdetect.csFindChessboardCornersSB(out overload)Modules/videoio/VideoCapture.csWaitAnyModules/aruco/Dictionary.csIdentifyModules/imgproc/FontFace.csGetInstanceModules/saliency/ObjectnessBING.csComputeSaliencyModules/face/Facemark/Facemark.csFitNo method in the public API is currently named
TryXxx(the onlyTryGetValue-style member isMatOfT<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
TryXxxmethod).Cv2_imgcodecs.cs,ImReadMulti/ImReadWithMetadata/ImReadAnimationonly null-check the filename (ArgumentNullException.ThrowIfNull), whileImRead/ImWrite/ImEncodereject empty strings too (string.IsNullOrEmpty) — soCv2.ImReadMulti("", out mats)silently returnsfalsewhereCv2.ImRead("")throws.Proposal (needs discussion, not decided yet)
Options to consider per method/family:
Tdirectly, with an empty/default value signaling failure (matchesMat's existing "return empty Mat on failure" convention used byImRead/ImDecode).TryXxxto make the contract explicit (matches BCL convention, e.g.int.TryParse).Given
OpenCvSharp5is 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+boolshape 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.