1

我想创建具有通用数据类型的通用图像类,如下面的代码所示。

在这个实现中,我不喜欢的是我必须像这样声明类: 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;
    }
}
4

2 回答 2

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取决于类型有不同的 s 的事实T 并不意味着所有IColor实现都必须依赖于类型T。可能存在IColor具有 0、2 或 9 个类型参数的实现——只要它们符合IColor(这很容易做到......)的实际合同,它们就可以了。

于 2013-04-18T14:52:53.347 回答
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);
        }
    }
    
于 2013-04-18T14:53:24.253 回答