当前位置:  开发笔记 > 编程语言 > 正文

有没有一种简单的方法来模拟C#中的Objective-C类别?

如何解决《有没有一种简单的方法来模拟C#中的Objective-C类别?》经验,为你挑选了0个好方法。

我有一个奇怪的设计情况,我以前从未遇到过......如果我使用Objective-C,我会用类别解决它,但我必须使用C#2.0.

首先,一些背景.我在这个类库中有两个抽象层.底层为扫描内容的组件实现了插件架构(抱歉,不能比这更具体).每个插件都会以一种独特的方式进行扫描,但插件也可能因其接受的内容类型而异.由于与本讨论无关的各种原因,我不想通过插件界面公开泛型.因此,我最终为每种内容类型提供了一个IScanner接口和一个派生接口.

顶层是一个便利包装器,它接受包含各种部分的复合内容格式.不同的扫描程序将需要复合的不同部分,具体取决于它们感兴趣的内容类型.因此,我需要具有特定于每个IScanner派生接口的逻辑,该接口解析复合内容,查找所需的相关部分.

解决此问题的一种方法是简单地向IScanner添加另一种方法并在每个插件中实现它.但是,双层设计的重点在于插件本身不需要了解复合格式.解决这个问题的蛮力方法是在上层进行类型测试和向下转换,但是需要谨慎维护这些方法,因为将来会添加对新内容类型的支持.在这种情况下,访客模式也很尴尬,因为实际上只有一个访问者,但不同的可访问类型的数量只会随着时间而增加(即 - 这些是访问者适合的相反条件).而且,当我真正想要的只是劫持IScanner的单一发送时,双重发送感觉就像矫枉过正!

如果我使用的是Objective-C,我只需在每个IScanner派生的接口上定义一个类别,并在那里添加parseContent方法.该类别将在上层定义,因此插件不需要更改,同时避免了类型测试的需要.不幸的是,C#扩展方法不起作用,因为它们基本上是静态的(即 - 与调用站点使用的引用的编译时类型相关联,而不是像Obj-C类别那样挂钩到动态调度).更不用说,我必须使用C#2.0,因此我甚至无法使用扩展方法.:-P

那么在C#中是否有一种简洁的方法来解决这个问题,类似于如何用Objective-C类别解决它?


编辑:一些伪代码,以帮助使当前设计的结构清晰:

interface IScanner
{ // Nothing to see here...
}

interface IContentTypeAScanner : IScanner
{
    void ScanTypeA(TypeA content);
}

interface IContentTypeBScanner : IScanner
{
    void ScanTypeB(TypeB content);
}

class CompositeScanner
{
    private readonly IScanner realScanner;

    // C-tor omitted for brevity... It takes an IScanner that was created
    // from an assembly-qualified type name using dynamic type loading.

    // NOTE: Composite is defined outside my code and completely outside my control.
    public void ScanComposite(Composite c)
    {
        // Solution I would like (imaginary syntax borrowed from Obj-C):
        // [realScanner parseAndScanContentFrom: c];
        // where parseAndScanContentFrom: is defined in a category for each
        // interface derived from IScanner.

        // Solution I am stuck with for now:
        if (realScanner is IContentTypeAScanner)
        {
            (realScanner as IContentTypeAScanner).ScanTypeA(this.parseTypeA(c));
        }
        else if (realScanner is IContentTypeBScanner)
        {
            (realScanner as IContentTypeBScanner).ScanTypeB(this.parseTypeB(c));
        }
        else
        {
            throw new SomeKindOfException();
        }
    }

    // Private parsing methods omitted for brevity...
}

编辑:为了澄清,我已经考虑过这个设计了很多.我有很多原因,其中大多数是我无法分享的,原因就在于它的原因.我还没有接受任何答案,因为虽然有趣,但他们回避了原来的问题.

事实是,在Obj-C中,我可以简单而优雅地解决这个问题.问题是,我可以在C#中使用相同的技术吗?如果是,如何使用?我不介意寻找替代方案,但公平地说这不是我问的问题.:)

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有