2014-09-22 1 views
1

어떻게 그러한 함수를 만들 수 있습니까? (프레임 워크는 Chr을 위해 어떻게합니까?) 또는 프레임 워크에서 가능한 이유는 무엇입니까? 대부분의 경우에 대한 해결 방법은 뭔가처럼Const from 함수

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() 

입니다 :

''' <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) 

MS reference source for ChrW

은 그래서 유사한 기능의 예를 생성 할 수 있어야한다 : consts의

예는 함수에서 선언

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

그러나 이것은 실제 값에 대한 인텔리 센스를 제공하지 않습니다.
이후로 "안전"하지 않음 it is possible to modify ReadOnly fields with reflection

그래서 'const 함수'를 선언 할 수있는 방법이 있습니까? 그렇지 않다면 프레임 워크가 실제로 어떻게합니까?

편집 :

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

는 컴파일러 특별한 경우이다 의미 생성 된 IL를 검사하였습니다.

+1

const는 함수 또는 표현식의 결과 일 수 없습니다. 컴파일 결과를 할당하려고 할 때 컴파일 타임에 알 필요가 있습니다. – Plutonix

+0

문서를보십시오 : [이니셜 라이저에서는 변수 나 함수를 사용할 수 없습니다. 그러나 CByte 및 CShort와 같은 전환 키워드를 사용할 수 있습니다. 상수 String 또는 Char 인수로 호출하면 AscW를 사용할 수도 있습니다. 컴파일 타임에 평가할 수 있으므로 AscW를 사용할 수 있습니다.] (http://msdn.microsoft.com/en-us/library/cyxe49xw.aspx). –

+0

예.이 모든 것은 컴파일 시간 평가에 관한 것입니다. 그래서'Chr' (0-127에만 해당)은'Asc'와 그 친구들을 컴파일 타임에 호출 할 수 있고'Const'로 사용할 수 있습니다. 'Const Cr As Char = ChrW (& HD)'가 작동하고'ChrW'가 함수이기 때문에 (http://referencesource.microsoft.com/Microsoft.VisualBasic/R/6283a83f3afbfba9.html) "const가 결과가 될 수 없습니다 함수 또는 표현의 "는 사실이 아닙니다. 따라서 질문은 여전히 ​​남아 있습니다. 이러한 기능의이면에있는 마법은 무엇이며, 왜 이러한 "컴파일 기능"을 만들 수 없습니까? – NiKiZe

답변

4

컴파일러는 특별한 경우로 AscW 및를 처리 할 수 ​​있습니다. "ASCW"에 대한 로슬린 소스 코드의 검색은 OptimizeLibraryCall (명확성을 위해 냈다 많은 ​​코드)에 다음과 같은 변합니다 :

  ' 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 

      '[...] 

특별히 컴파일의 종류에 AscWChrW을 언급 EarlyWellKnownAttributeBinder.CanBeValidAttribute에 댓글도 있습니다 속성 값에 사용될 수 - 시간 상수 :

 ' 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 

모노 vbnc 컴파일러는 IsConstantMethodhelper method는 이러한 기능을 지원해야하는 것 (이것은 특히 상기 방법은 AscW,여부 확인 또는 특수한 경우임을 암시하는 const 문을 허용하는지 여부를 테스트하기 위해 test case과 함께 제공됩니다.

당신이 ILDASM에서 컴파일 된 어셈블리를 보면, 당신은 볼 수 있습니다 :

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

당신은 컴파일러 기능을 평가하고 그 결과를 방출되는 것을 볼 수 있습니다 - 그것은 상수 "모든 종류의 내장 아니에요 함수 "를 호출하고 참조 소스의 함수에서"상수 함수 "로 표시하는 속성 장식은 없습니다.

여러분의 질문에 답하기 위해 컴파일러는 특수한 하드 코딩 된 케이스로 문자열 함수를 처리하여 컴파일러 코드를 작성하는 것처럼 보이며 컴파일러 코드를 수정하지 않아도되는 것처럼 보이지 않습니다.MSDN에서

+0

감사합니다. 일리노이 자신을 diggd하고 생성 된 리터럴 +1을 실제로 설명하는 소스에 대한 참조를 제공하는 것을 보았습니다. 보너스 포인트는 Const로 사용할 수있는 인라인 IL을 작성할 수 있습니까? – NiKiZe

0

:

당신은 초기화에서 변수 나 함수를 사용할 수 없습니다. 은 CByte 및 CShort와 같은 전환 키워드를 사용할 수 있습니다. 상수 String 또는 Char 인수를 사용하여 호출하면 AscW를 사용할 수도 있습니다. 은 컴파일 시간이이므로 평가할 수 있습니다.

Private Const vblf As String = ChrW(10) 

가 컴파일 : 등

CHRW 컴파일러가이를 수 있도록 설계되어 있기 때문에 특별하다 NET 기능을 사용하여

private const char vblf = '\n'; 

대부분의 다른 형태의 불법 :

Private Const vbcr As String = Convert.ToString(New Byte() {13}) 
Private Const vblf2 As Char = Environment.NewLine 

Private Const Z As String = Ziggy.ToLower 

Ziggy 상수이기 때문에 합법적이어야하며 함수 결과는 그렇지 않습니다. 문자열이 일치하지 않아야 할 때 런타임에 매우 불쾌한 문제를 만드는 영어가 아닌 시스템에서 반환 값이 다를 수 있습니다.

+0

"컴파일러가 허용하도록 설계되었습니다"는 내가 누락 된 부분이 많든 적든간에. 그래서 재미있는 부분이 일리노이를 검사 할 때 나타났습니다. 그래서 "Compiles to"C 구문은 다소 혼란 스럽거나 오도 된 것입니다. – NiKiZe

+0

그것은 Chr에 대한 호출을 최적화하고 단순히 Const 선언에서 리턴 값을 사용합니다. – Plutonix