【问题标题】:Translate C# delegates onto TypeScript将 C# 委托翻译成 TypeScript
【发布时间】:2012-11-18 18:19:21
【问题描述】:

你能告诉我如何把它翻译成TypeScript吗? 使用 SharpKit.JavaScript;

namespace MyNamespace
{
    [JsType(JsMode.Prototype)]
    public class JsEventArgs
    {
    }

    public delegate void JsEventHandler<in T>(object sender, T args) where T : JsEventArgs;
    public delegate void JsEventHandler(object sender, JsEventArgs args);
}

以及在其他类中的用法:

public event JsEventHandler<LayerVisivilityEventArgs> Changed;

我试过了:

module JsEvent {

    export class JsEventArgs {
    }

    public JsEventHandler: (sender: Object, args: any) => void;
    public JsEventHandler: (sender: Object, args: JsEventArgs) => void;
}

【问题讨论】:

  • 我对你想要做什么感到困惑。 SharpKit 和 TypeScript 有什么关系?
  • 我正在将一个 C# 应用程序翻译成 TypeScript。我想创建一个事件,该事件将作为 C# 代码中的事件。
  • 您在上面尝试过的 TypeScript 有什么问题?
  • 这不是因为它们是公开的,而是因为您无法向模块添加属性。
  • 问题一点都不清楚。那 JsEventHandler 和 JsEventArgs 和 JsMode —— 有人怎么会猜到它们的目的?您需要清楚地定义您要实现的目标,而不是在没有任何解释的情况下提供原始源代码。

标签: c# javascript typescript


【解决方案1】:

我写了一个小类,其行为类似于 .NET Delegate 类(它是为 .NET 中的事件隐式创建的)

export interface IDelegate {
    (sender: any, ...parameters: any[]): void;
}

export class DelegateBuilder {
    private callees: IDelegate[];

    constructor() {
        this.callees = [];
    }

    invoke(sender: any, ...parameters: any[]) {
        for (var i = 0; i < this.callees.length; i++) {
            var callee = this.callees[i];
            if (caller)
                callee(sender, parameters);
        }
    }

    contains(callee: IDelegate) : bool {
        if (!callee)
            return false;

        return this.callees.indexOf(callee) >= 0;
    }

    add(callee: IDelegate): DelegateBuilder {
        if (!callee)
            return this;

        if (!this.contains(callee))
            this.callees.push(callee);

        return this;
    }

    remove(callee: IDelegate): DelegateBuilder {
        if (!callee)
            return this;

        var index = this.callees.indexOf(callee);
        if (index >= 0)
            this.callees.splice(index, 1);

        return this;
    }

    toDelegate() : IDelegate {
        return (sender: any, ...parameters: any[]) => this.invoke(sender, parameters);
    }
}

【讨论】:

    【解决方案2】:

    我认为你需要停止思考 C#,而开始思考 TypeScript。

    这段代码:

    module JsEvent {
    
        export class JsEventArgs {
        }
    
        public JsEventHandler: (sender: Object, args: any) => void;
        public JsEventHandler: (sender: Object, args: JsEventArgs) => void;
    }
    

    ... 尝试向模块添加两个属性,但属性只允许在类(或接口)上。

    TypeScript 并不真正使用委托 - 您可以连接一个事件(例如,在 JQuery 中),如下所示:

    $('selector').click((e:JQueryEventObject) => {
         // Do something here.
    });
    

    ...或者,避免使用 JQuery:

    var div: HTMLDivElement = new HTMLDivElement();
    div.onclick = (e: MouseEvent) => {
        // Do something here.
    };
    

    ...或者,没有匿名函数:

    div.onclick = doSomething;
    function doSomething(e:MouseEvent):void{
        // Do something here.
    }
    

    我认为最接近委托的模式是这样的(抄自http://forum.unity3d.com/threads/9679-Javascript-Delegates!):

    module JSEvents {
        class JSEventClass {
    
            public delegate:(e:string) => any;
    
            constructor() => {
                this.delegate = this.doSomething;
                this.delegate("Hello, Delegate World");
            }
    
            public doSomething(e: string): any {
                console.log("Doing Something: " + e);
            }
        }
    }
    

    ...但是在 TypeScript / JavaScript 世界中,我看不出这种模式与直接调用 doSomething() 相比能实现什么。

    【讨论】:

    • 在委托中封装公共调用签名对于重用和可读性很有用。
    【解决方案3】:

    我认为这是有问题的代码的近似翻译。但是,这并没有解决事件处理问题,another answer 已经涵盖了这一点。

    module MyNamespace
    {
        export class JsEventArgs
        {
        }
    
        export interface JsEventHandler<T extends JsEventArgs> {
            (sender: any, args: T): void;
        }
    
        export interface JsEventHandler {
            (sender: any, args: JsEventArgs): void;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-22
      • 2012-11-20
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      • 1970-01-01
      相关资源
      最近更新 更多