Я всегда считал, что подходящий способ справиться с этим зависит от целевой аудитории и того, как будет использоваться ваш класс.
Если вызывающий ваш класс / метод поймет, что он вызывает Win32 в той или иной форме, я бы использовал вариант 1), который вы указали. Это кажется самым «понятным» для меня. (Однако, если это так, я бы назвал ваш класс таким образом, чтобы было ясно, что Win32 API будет использоваться напрямую). При этом в BCL есть исключения, которые на самом деле подкласс Win32Exception, чтобы быть более понятным, а не просто обернуть его. Например, SocketException происходит от Win32Exception. Я никогда не использовал этот подход лично, но он кажется потенциально чистым способом справиться с этим.
Если вызывающая сторона вашего класса не будет знать, что вы вызываете Win32 API напрямую, я бы обработал исключение и использовал пользовательское, более описательное исключение, которое вы определили. Например, если я использую ваш класс, и нет никаких признаков того, что вы используете API-интерфейс Win32 (поскольку вы используете его внутри по какой-то конкретной, неочевидной причине), у меня не было бы оснований подозревать, что я может потребоваться обработать Win32Exception. Вы всегда можете задокументировать это, но мне кажется более разумным отловить это и дать исключение, которое будет иметь большее значение в вашем конкретном бизнес-контексте. В этом случае я мог бы обернуть исходное исключение Win32Exception как внутреннее исключение (т. Е. Ваш случай 4), но в зависимости от того, что вызвало внутреннее исключение, я мог бы этого не делать.
Кроме того, во многих случаях Win32Exception генерируется из собственного вызова, но в BCL есть и другие исключения, которые более актуальны. Это тот случай, когда вы вызываете нативный API, который не упакован, но есть аналогичные функции, которые ОБРАТЕНЫ в BCL. В этом случае я бы, вероятно, перехватил исключение, удостоверился, что это именно то, что я ожидал, но затем бросил бы стандартное исключение BCL на его место. Хорошим примером этого является использование SecurityException вместо создания Win32Exception.
В общем, я бы избегал указанных вами вариантов 2 и 3.
Вариант два генерирует общий тип исключения - я бы очень рекомендовал избегать этого полностью. Кажется неразумным заключать конкретное исключение в более обобщенное.
Вариант три кажется избыточным - на самом деле нет преимущества перед вариантом 1.