来自函数的常量 [英] Const from function

查看:23
本文介绍了来自函数的常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何创建这样的函数?(框架是如何为Chr做的)或者为什么不可能,但在框架中是可能的?

How can such a function be created? (How do the framework do it for Chr) Or why is it not possible, but possible in the framework?

从函数声明的常量示例:

Example of consts declared from function:

''' <summary>Carriage Return \r 13 0xD</summary>
Public Const Cr As Char = ChrW(&HD)
''' <summary>Line Feed \n 10 0xA</summary>
Public Const Lf As Char = ChrW(&HA)

ChrW 的 MS 参考源

所以应该可以创建类似的函数,例如:

So it should be possible to create similar functions ex:

Public Const Magic As String = "Magic" ' ok
Public Const lcMagic As String = Magic.ToLower ' not ok - wanted to avoiding potential bugs if Magic is ever changed.
Public Const Magic2 As String = functionGeneratingLongButStaticString()

大多数情况下的解决方法如下:

A workaround for most cases is something like:

''' <summary>Lowercase value of Magic</summary>
Public Shared ReadOnly lcMagic As String = Magic.ToLower

但这并不能提供实际价值的智能感知.
而不是安全",因为 它是可以通过反射修改只读字段

But this do not provide intellisense of the actual value.
And not "secure" since it is possible to modify ReadOnly fields with reflection

那么有没有什么方法可以声明'const 函数',如果没有,框架是如何做到的?

So is there any way to declare 'const functions' at all, and if not, how do the framework really do it?

检查生成的IL:

.field public static literal char Cr = char('\r')

这意味着它是编译器的特殊情况.

Which means it is a special case for the compiler.

推荐答案

编译器可能将 AscWChrW 视为特殊情况.在 Roslyn 源代码中搜索AscW"会在 OptimizeLibraryCall(为了清晰起见,剪掉了很多代码):

The compiler may be treating AscW and ChrW as special cases. A search of the Roslyn source code for "AscW" turns up the following in OptimizeLibraryCall (lots of code snipped for clarity):

            ' AscW(char) / AscW(String)
            ' all values can be optimized as a literal, except an empty string that produces a diagnostic
            If IsWellKnownTypeMember(WellKnownMember.Microsoft_VisualBasic_Strings__AscWCharInt32, method) OrElse
                IsWellKnownTypeMember(WellKnownMember.Microsoft_VisualBasic_Strings__AscWStringInt32, method) Then

                '[...]
                Return ConstantValue.Create(AscW(argumentValue))
            End If

            ' ChrW
            ' for -32768 < value or value > 65535 we show a diagnostic
            If IsWellKnownTypeMember(WellKnownMember.Microsoft_VisualBasic_Strings__ChrWInt32Char, method) Then
                '[...]
                Return ConstantValue.Create(ChrW(argumentValue))
            End If

            '[...]

EarlyWellKnownAttributeBinder 中还有一条评论.CanBeValidAttribute 在可用于属性值的编译时常量类型中特别提到了 AscWChrW:

There's also a comment in EarlyWellKnownAttributeBinder.CanBeValidAttribute that specifically mentions AscW and ChrW in the types of compile-time constants that can be used for attribute values:

        ' 11.2 Constant Expressions
        '
        'A constant expression is an expression whose value can be fully evaluated at compile time. 
        ' [...]
        '         The following run-time functions:
        '            Microsoft.VisualBasic.Strings.ChrW
        '            Microsoft.VisualBasic.Strings.Chr, if the constant value is between 0 and 128
        '            Microsoft.VisualBasic.Strings.AscW, if the constant string is not empty
        '            Microsoft.VisualBasic.Strings.Asc, if the constant string is not empty

Mono vbnc 编译器似乎有一个 IsConstantMethod helper 方法来支持这些功能(它专门检查方法是否为AscW, Asc, ChrWChr),以及 测试用例 专门用于测试 const 语句是否接受这些函数,这表明它们是特殊情况.

The Mono vbnc compiler seems to have an IsConstantMethod helper method to support these functions (it specifically checks whether the method is AscW, Asc, ChrW, or Chr), along with a test case specifically to test whether const statements accept those functions, which suggests they are special cases.

如果您在 ildasm 中查看已编译的程序集,您会看到:

If you look at your compiled assembly in ildasm, you'll see:

.field public static literal char Cr = char(0x000D)

您可以看到编译器正在评估函数并发出结果——它没有嵌入任何类型的常量函数"调用,并且参考源中的这些函数没有任何类型的属性修饰将它们标记为一个常数函数".

You can see that the compiler is evaluating the function and emitting the result -- it's not embedding any sort of "constant function" call, and there's not any sort of attribute decoration on those functions in the reference source that marks them as a "constant function".

所以为了回答您的问题,看起来编译器通过将这些字符串函数视为特殊的硬编码案例来做到这一点,而且除了修改编译器代码之外,似乎没有任何方法可以做到这一点.

So to answer your questions, it looks like the compiler does this by treating those string functions as special hardcoded cases, and it doesn't look like there's any way to do so, short of modifying the compiler code.

这篇关于来自函数的常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆