C#通用类中的调用方法

时间:2010-03-14 20:14:41

标签: c# .net generics casting

我正在从EmguCV扩展ImageBox控件。控件的Image属性可以设置为实现IImage接口的任何内容。

以下所有实现此接口:

Image<Bgr, Byte>
Image<Ycc, Byte>
Image<Hsv, Byte>

现在我想在上述类型的对象上调用Draw方法(无论它是什么)。

问题是当我访问Image属性时,返回类型为IImage。 IImage没有实现Draw方法,但上述所有方法都是如此。

我相信我可以将IImage类型的对象转换为上面的一个(右边的),然后我可以访问Draw方法。但我怎么知道正确的是什么?如果您有更好的方法,请同时提出建议。

修改

很抱歉,但我忘了提一条重要信息。上述每个类的Draw方法都有一个不同的参数。对于例如Draw的{​​{1}}采用Image<Bgr, Byte>类型的参数,Bgr的{​​{1}}采用类型为Draw的参数。

7 个答案:

答案 0 :(得分:3)

添加一个继承自IImage的IDrawableImage。

public interface IDrawableImage : IImage
{
   void Draw(object val);
   void Draw();
}

然后您可以简单地执行以下操作:

var drawableImage = container.Image as IDrawableImage;
if (drawableImage != null)
    drawableImage.Draw();

符合上述说明:

public interface IDrawableImage<T, B> : IDrawableImage where B : byte
{
    void Draw<T>(T val);
}

然后如果您知道类型:

var value = new Hvr();
var drawableImage = container.Image as IDrawableImage<Hvr, Byte>;
if (drawableImage != null)
    drawableImage.Draw(value);

如果你不

var value = new Hvr();
var drawableImage = container.Image as IDrawableImage;
if (drawableImage != null)
    drawableImage.Draw(value);

答案 1 :(得分:1)

如果我理解正确 - Image类实现了draw方法。我不知道你将如何使用它,但你可以这样做:

private void DrawImage<T1, T2>(Image<T1, T2> image)
{
    image.Draw();
}

上面的主要问题是上述方法的调用者应该指定T1和T2类型。

如果您无法控制IImage接口及其实现,那么我认为您将从两个解决方案中进行选择:指定T1和T2类型,或者使用ifs / switch以及所有可能的IImage实现。

如果您可以访问IImage接口和Image类,那么您应该添加通用IImage接口并向其添加Draw方法。

答案 2 :(得分:1)

你应该有一个添加Draw()的共享界面。

答案 3 :(得分:0)

这样的事情怎么样:

void foo( IImage image )
{
    if ( image is Image<Bgr, Byte> )
    {
        ((Image<Bgr, Byte>)(image)).Draw();
    }

    // handle the other types the same way.
}

答案 4 :(得分:0)

如果你确定Image&lt; T,U&gt;您将拥有(无论类型)将具有Draw方法,您可以使用反射和黑客围绕它:

我会将其作为扩展方法:

public static void Draw(this IImage image)
{
   var method = image.GetType().GetMethod("Draw");
   if(method != null)
   {
      method.Invoke(image,null);
   }
}

有点黑客,但话说回来,我会说API没有正确设计。至少应该有一些Drawer类或者知道如何对图像进行操作的东西。

答案 5 :(得分:0)

您的问题缺少一条重要的信息:您想写的代码。

我们需要知道你打算如何编写调用Draw(...)方法的代码。

答案 6 :(得分:0)

或者,您可以使用动态方法并抓住机会。