microsoft / ClearScript

A library for adding scripting to .NET applications. Supports V8 (Windows, Linux, macOS) and JScript/VBScript (Windows).
https://microsoft.github.io/ClearScript/
MIT License
1.77k stars 148 forks source link

Extension method for primitives types #554

Closed sergioamm17 closed 10 months ago

sergioamm17 commented 10 months ago

Is it possible to add extrension methods to primitive type? For example, I already created a method for String, however the script doesn't reconigze the method.

ClearScriptLib commented 10 months ago

Hi @sergioamm17,

Is it possible to add extrension methods to primitive type?

If you're using V8, then yes. It just takes a little extra setup. Suppose your extension type looks like this:

public static class Extensions {
    public static void SayHello(this object obj) {
        Console.WriteLine("Hello! I am '{0}'.", obj);
    }
}

You can use it with primitive values on the .NET side:

"foo".SayHello();
123.456.SayHello();

Here's how to add SayHello on the JavaScript side:

dynamic addExtension = engine.Evaluate(@"
    (ctor, extType, name) => 
        ctor.prototype[name] = function () { return extType[name](this.valueOf()); }
");
addExtension(engine.Script.Object, typeof(Extensions).ToHostType(engine), "SayHello");

And now you can do this:

engine.Execute(@"
    'foo'.SayHello();
    123.456.SayHello();
");

Good luck!

sergioamm17 commented 10 months ago

Thanks for your response,

Can we create an extension method direct to a Type as String?
We already have this kind of extension over specific types (String Int), but, we are no using the object type directly For example:


public static class Extensions {
    public static void TestString(this string input, string value) {
        Console.WriteLine($"Hello! I am {value}");
    }
}```
ClearScriptLib commented 10 months ago

Can we create an extension method direct to a Type as String?

Sure. The first argument to addExtension specifies the target JavaScript constructor. For example (this also shows how to pass additional arguments to the extension method):

dynamic addExtension = engine.Evaluate(@"
    (ctor, extType, name) => 
        ctor.prototype[name] = function () { return extType[name](this.valueOf(), ...arguments); }
");
addExtension(engine.Script.String, typeof(Extensions).ToHostType(engine), "TestString");

And now:

"foo".TestString("bar");
engine.Execute("'foo'.TestString('bar');");

Cheers!

sergioamm17 commented 10 months ago

Thank you so much, this is really helpful.

Best regards