我目前正在撰寫一個以 qoi 格式編碼和解碼影像的庫。此影像格式使用 rgb 和 rgba 像素格式。
我做了IPixel
介面和兩個實作RgbPixel
和RgbaPixel
. IPixel
不打算用作擴展點(因為只有rgb和rgba),我使這個介面使用泛型類,以免重復撰寫相同的東西。
RgbPixel
并且RgbaPixel
是具有[StructLayout]
屬性的結構。我的一些泛型類使用不安全代碼將這些結構和其他非托管型別不安全地相互轉換以提高性能,因此如果用戶/另一個實作IPixel
獲取它們,它很可能會導致例外。
為了避免所有這些問題,我想只允許IPixel
介面的內部實作。但我不知道如何在 C# 中做到這一點。
如果IPixel
是一個抽象類,我可以通過只有內部建構式來阻止其他程式集的實作。但我只能使用介面,因為我需要RgbPixel
并RgbaPixel
成為結構。
.netstandart 2.0, c# 10.0
uj5u.com熱心網友回復:
我會制作IPixel
內部并擁有接受的公共 shim 方法,然后呼叫接受RgbPixel
的RgbaPixel
公共方法IPixel
(或基類)。
uj5u.com熱心網友回復:
我將所有類建構式都設為內部并添加了兩個靜態方法Load
,New<T>
第一個方法采用編碼資料并通過解碼它創建的標頭QImage<RgbPixel>
或QImage<RgbaPixel>
,第二種方法僅檢查用戶傳遞的型別引數,如 Kirk Woll 所建議的那樣評論。
看起來像這樣:
public class QImage : IImage {
internal QImage(/*args*/) { /*...*/ }
public static QImage Load(byte[] bytes) {
//...
var qr = new QoiBytesReader(bytes);
var qHeader = Decoder.DecodeHeader(ref qr);
//ugly :|
return qHeader.Channels == Channels.Rgb
? new QImage<RgbPixel>(Decoder.DecodePixels<RgbPixel>(ref qr, in qHeader), qHeader)
: new QImage<RgbaPixel>(Decoder.DecodePixels<RgbaPixel>(ref qr, in qHeader), qHeader);
}
//...
}
public class QImage<T> : QImage where T : unmanaged, IPixel {
internal QImage(/*args*/) : base(/*params*/) { /*...*/ }
public static QImage<T> New(byte[] pixels, QHeader qHeader) {
if (typeof(T) == typeof(RgbPixel) || typeof(T) == typeof(RgbaPixel))
return new QImage<T>(pixels, qHeader);
throw new NotSupportedException($"Specified type <{typeof(T).Name}> is not supported. Use <{nameof(RgbPixel)}> or <{nameof(RgbaPixel)}> instead.");
}
//...
}
internal static unsafe class Decoder {
internal static byte[] DecodePixels<T>(ref QoiBytesReader qr, in QHeader metadata)
where T : unmanaged, IPixel { /*decode*/ }
//...
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/496818.html
標籤:C# 。网 遗产 界面 .net-standard-2.0