我想创建具有通用数据类型的通用图像类,如下面的代码所示。
在这个实现中,我不喜欢的是我必须声明类如下:
Image<BGR<byte>, byte> a;
而不是:
Image<BGR, byte> a;
有没有办法实现这个目标?
public interface IColor<T>
{ }
public struct BGR<T>: IColor<T>
{
public T B;
public T G;
public T R;
}
public class Image<TColor, T> where TColor: IColor<T>
{
TColor[,] data;
}
class Program
{
static void Main(string[] args)
{
Image<BGR<byte>, byte> a;
}
}
答案 0 :(得分:2)
我所做的一切都是IColor
非一般的,并通过以下方式进行:
public interface IColor
{ }
public struct BGR<T>: IColor
{
public T B;
public T G;
public T R;
}
public class Image<TColor> where TColor: IColor
{
TColor[,] data;
}
class Program
{
static void Main(string[] args)
{
Image<BGR<byte>> a;
}
}
根据类型BGR
存在不同T
s的事实不需要意味着所有IColor
实现都必须依赖于类型{ {1}}。可以T
实现零,2或9类型参数 - 只要它们符合IColor
的实际合约(这很容易做到......),它们就可以了。
答案 1 :(得分:1)
代码
public interface IColor<T> {
IColor<U> FromColor<U>(IColor<U> color);
}
public class Bgr: IColor<byte>, IColor<int> /* .. more IColor<T> */ {
public IColor<T> FromColor<T>(IColor<T> color) {
if(null==color)
return default(Bgr<T>);
if(color is Bgr)
return color;
if(color is Bgr<T>)
return new Bgr {
Value=color
} as IColor<T>;
throw new NotImplementedException();
}
public object Value;
}
public struct Bgr<T>: IColor<T> {
IColor<U> IColor<T>.FromColor<U>(IColor<U> color) {
if(null==color)
return default(Bgr<U>);
if(color is Bgr)
return (Bgr<U>)(color as Bgr).Value;
if(color is Bgr<U>)
return color;
throw new NotImplementedException();
}
public T B, G, R;
}
public class Image<TColor, T> where TColor: IColor<T>, new() {
public static Array CreateArray(params int[] lengths) {
var color=(new TColor()).FromColor(default(TColor));
return Array.CreateInstance(color.GetType(), lengths);
}
public Image(params int[] lengths) {
data=Image<TColor, T>.CreateArray(lengths);
}
public Array data; // expose for test
}
测试
public class TestClass {
public static void TestMethod() {
var image=new Image<Bgr, byte>(640, 480);
var data=(Bgr<byte>[,])image.data;
var bgr=new Bgr<byte>();
bgr.B=123;
data[0, 0]=bgr;
data[0, 0].G=124;
bgr=data[0, 0];
Console.WriteLine("bgr{{B={0}, G={1}, R={2}}}", bgr.B, bgr.G, bgr.R);
}
}