提问人:ElektroStudios 提问时间:7/7/2023 最后编辑:ElektroStudios 更新时间:7/7/2023 访问量:51
在 ClearScript 中使用匿名类型时禁止显示不相关的成员
Suppress irrelevant members when using an anonymous type in ClearScript
问:
我正在围绕 java 脚本库实现 https://linkify.js.org/ .NET 包装器。对于这个任务,我使用的是Microsoft的ClearScript。
我遇到的唯一问题是在实现在 linkifyHtml 函数的 options 对象参数中传递的 attributes 属性时。
该函数需要在 java 脚本代码中出现如下参数:
attributes: {
title: "External Link",
etc: "etc..."
}
所以,我的想法是定义这个属性,它返回一个匿名类型:Attributes
Public Class LinkifyFormatOptions
Public Property Attributes As Func(Of LinkifyLinkType, String, Object) =
Function(linkType As LinkifyLinkType, href As String) As Object
Select Case linkType
Case LinkifyLinkType.Url
Return New With {.test_attribute = "This is a test attribute"}
Case Else
Return Nothing
End Select
End Function
End Class
...稍后我将调整其返回值以构建选项对象:
Friend Function GetLinkifyOptions() As Object
Dim options As New With {
.attributes = Function(href As String, linkType As String) As Object
Select Case linkType
Case "url"
Return Me.Attributes(LinkifyLinkType.Url, href)
Case "email"
Return Me.Attributes(LinkifyLinkType.Email, href)
Case "hashtag"
Return Me.Attributes(LinkifyLinkType.Hashtag, href)
Case "mention"
Return Me.Attributes(LinkifyLinkType.Mention, href)
Case "ticket"
Return Me.Attributes(LinkifyLinkType.Ticket, href)
Case Else
Return Nothing
End Select
End Function,
.className = etc...,
.formatHref = etc...,
.etc = etc...
}
End Function
...最后在此处调用 java-script 的函数:linkifyHtml
Imports Microsoft.ClearScript
Imports Microsoft.ClearScript.V8
Public Shared Function Linkify(str As String,
[interface] As LinkifyInterface,
Optional plugins As LinkifyPlugins = LinkifyPlugins.None,
Optional formatOptions As LinkifyFormatOptions = Nothing) As String
' Argument validations and etc...
Using engine As New V8ScriptEngine("linkify_engine", V8ScriptEngineFlags.DisableGlobalMembers)
Dim options As Object = formatOptions.GetLinkifyOptions()
' linkify.js scripts loading and etc...
Dim linkifyFunction As ScriptObject = DirectCast(engine.Evaluate("linkifyHtml"), ScriptObject)
Return CStr(linkifyFunction.Invoke(asConstructor:=False, str, options))
End Using
End Function
问题在于 ClearScript 引擎公开了该类型的成员,如“ToString”方法、“GetHashCode”等。Object
这是我调用 java-script 函数后得到的输出:linkifyHtml
<p>Domain: <a href="http://example.domain.com" $test_attribute="This is a test attribute" ToString="[object Object]" Equals="[object Object]" GetHashCode="[object Object]" GetType="[object Object]" Finalize="[object Object]" MemberwiseClone="[object Object]" test_attribute="This is a test attribute" toJSON="function toJSON() { [native code] }">example.domain.com</a></p>
我通过启用 V8ScriptEngine.SuppressInstanceMethodEnumeration 属性部分解决了这个问题,如下所示:
Using engine As New V8ScriptEngine("linkify_engine", V8ScriptEngineFlags.DisableGlobalMembers)
engine.SuppressInstanceMethodEnumeration = True
' etc...
End Using
但是,输出中仍然存在反射函数和其他垃圾,我不知道如何摆脱它:toJSON
<p>Domain: <a href="http://example.domain.com" $test_attribute="This is a test attribute" test_attribute="This is a test attribute" toJSON="function toJSON() { [native code] }">example.domain.com</a></p>
当然,所需的输出将是这样的:
<p>Domain: <a href="http://example.domain.com" test_attribute="This is a test attribute">example.domain.com</a></p>
然后,我想知道如何抑制该反射成员以及以“$”符号开头的成员,例如 .toJSON
$test_attribute
我认为也许我需要替换和调整匿名类型用法,以适应从命名空间继承或实现特定接口的限定类型和/或可能还使用特定的属性类,所有这些都是为了让 V8 引擎以正确的方式做事......但我不知道该怎么做。Microsoft.ClearScript
我试图定义一个自定义类型,我用它来重新定义(阴影或覆盖)和其他成员,然后我试图在这些重新定义的成员中应用各种属性类,以试图在 ClearScript 引擎中“隐藏”它们,但没有成功。无论如何,我不知道它来自哪里的功能。ToString
GetHashCode
Equals
toJSON
答:
我可以用这个简化的代码重现你的问题:
Dim attributes = New With {.test_attribute = "This is a test attribute"}
Dim options = New With {.attributes = attributes}
Console.WriteLine(engine.Script.linkifyHtml("example.domain.com", options))
评论:该属性似乎是匿名类型的一部分,ClearScript 在公开它时可能做了正确的事情。另一方面,作为可枚举属性的存在可能是 ClearScript 中的一个错误。$test_attribute
toJSON
建议:不要使用匿名类型,而应使用脚本对象。下面是一个创建并填充脚本对象的函数:
Private Function CreateObject(engine As V8ScriptEngine, ParamArray props() As (name As String, value As Object))
Dim result = engine.Evaluate("({})")
For Each prop In props
result(prop.name) = prop.value
Next
CreateObject = result
End Function
您可以使用该函数来获取所需的行为:
Dim attributes = CreateObject(engine, ("test_attribute", "This is a test attribute"))
Dim options = CreateObject(engine, ("attributes", attributes))
Console.WriteLine(engine.Script.linkifyHtml("example.domain.com", options))
评论
GetLinkifyOptions
评论