Reputation: 9714
I am extending the ImageBox control from EmguCV. The control's Image
property can be set to anything implementing the IImage
interface.
All of the following implement this interface:
Image<Bgr, Byte>
Image<Ycc, Byte>
Image<Hsv, Byte>
Now I want to call the Draw
method on the object of the above type (what ever it may be).
The problem is when I access the Image property, the return type is IImage
. IImage does not implement the Draw
method, but all of the above do.
I believe I can cast the object of type IImage
to one of the above (the right one) and I can access the Draw
method. But how do I know what the right one is? If you have a better way of doing this, please suggest that as well.
EDIT
Sorry, but I forgot to mention an important piece of information. The Draw method for each of the above class takes one different argument. For e.g. Draw
for Image<Bgr, Byte>
takes an argument of type Bgr
and the Draw
for Image<Hsv, Byte>
takes an argument of type Hsv
instead.
Upvotes: 6
Views: 1844
Reputation: 45445
Your question is missing a critical piece of information: the code you would like to write.
We need to know how you intend to write the code which calls the Draw(...)
method.
Upvotes: 0
Reputation: 16032
If I understood you correctly - Image class implements draw method. I don't know how you are going to use it, but you can do in this way:
private void DrawImage<T1, T2>(Image<T1, T2> image)
{
image.Draw();
}
The main problem about above is that the caller of the above method should specify the T1 and T2 types.
If you don't have control about IImage interface and its implementations then I think you will be choosing from two solutions: specify T1 and T2 types or having ifs/switches with all possible IImage implementations.
If you have access to the IImage interface and Image class then you should add generic IImage interface and add Draw method to it.
Upvotes: 1
Reputation: 10827
Add an IDrawableImage that inherits from IImage.
public interface IDrawableImage : IImage
{
void Draw(object val);
void Draw();
}
Then you can simply do the following:
var drawableImage = container.Image as IDrawableImage;
if (drawableImage != null)
drawableImage.Draw();
To match your clarification above:
public interface IDrawableImage<T, B> : IDrawableImage where B : byte
{
void Draw<T>(T val);
}
then if you know the type:
var value = new Hvr();
var drawableImage = container.Image as IDrawableImage<Hvr, Byte>;
if (drawableImage != null)
drawableImage.Draw(value);
if you don't
var value = new Hvr();
var drawableImage = container.Image as IDrawableImage;
if (drawableImage != null)
drawableImage.Draw(value);
Upvotes: 3
Reputation: 103740
If you're sure that the Image<T,U> that you'll have (regardless of the types) will have the Draw method, you can use reflection and hack around it:
I would do it as an extension method:
public static void Draw(this IImage image)
{
var method = image.GetType().GetMethod("Draw");
if(method != null)
{
method.Invoke(image,null);
}
}
A bit of a hack, but then again, I would say that the API isn't properly designed. There should at least be some Drawer class or something that would know how to act on an image.
Upvotes: 0
Reputation: 8937
How about something like this:
void foo( IImage image )
{
if ( image is Image<Bgr, Byte> )
{
((Image<Bgr, Byte>)(image)).Draw();
}
// handle the other types the same way.
}
Upvotes: 0