diff --git a/docs/csharp/12-expressions.md b/docs/csharp/12-expressions.md index 202ce23d1..e34de2558 100644 --- a/docs/csharp/12-expressions.md +++ b/docs/csharp/12-expressions.md @@ -2840,80 +2840,28 @@ comma ``` -The first form of *typeof_expression* consists of a `typeof` keyword followed by a parenthesized type. The result of an expression of this form is the `System.Type` object for the indicated type. There is only one `System.Type` object for any given type. This means that for a type `T`, `typeof(T) == typeof(T)` is always true. The type cannot be `dynamic`. +The `typeof` operator is not supported in neo C# smart contracts, as the `System.Type` type is not available in this context. However, there is one exception: `typeof` can be used directly as a parameter value in certain Neo-specific attributes or method calls. -The second form of *typeof_expression* consists of a `typeof` keyword followed by a parenthesized *unbound_type_name*. +> [!WARNING] +> Using `typeof` in any other context within a Neo smart contract will result in a compilation error. -> *Note*: An *unbound_type_name* is very similar to a *type_name* ([§7.8](7-basic-concepts.md#78-namespace-and-type-names)) except that an *unbound_type_name* contains *generic_dimension_specifier*s where a *type_name* contains *type_argument_list*s. *end note* +For example, you might see `typeof` used in this way: -When the operand of a *typeof_expression* is a sequence of tokens that satisfies the grammars of both *unbound_type_name* and *type_name*, namely when it contains neither a *generic_dimension_specifier* nor a *type_argument_list*, the sequence of tokens is considered to be a *type_name*. The meaning of an *unbound_type_name* is determined as follows: - -- Convert the sequence of tokens to a *type_name* by replacing each *generic_dimension_specifier* with a *type_argument_list* having the same number of commas and the keyword `object` as each *type_argument*. -- Evaluate the resulting *type_name*, while ignoring all type parameter constraints. -- The *unbound_type_name* resolves to the unbound generic type associated with the resulting constructed type ([§8.4](8-types.md#84-constructed-types)). - -The result of the *typeof_expression* is the `System.Type` object for the resulting unbound generic type. - -The third form of *typeof_expression* consists of a `typeof` keyword followed by a parenthesized `void` keyword. The result of an expression of this form is the `System.Type` object that represents the absence of a type. The type object returned by `typeof(void)` is distinct from the type object returned for any type. - -> *Note*: This special `System.Type` object is useful in class libraries that allow reflection onto methods in the language, where those methods wish to have a way to represent the return type of any method, including `void` methods, with an instance of `System.Type`. *end note* +```csharp +public static object TestEnumParse(string value) +{ + // var type = typeof(TestEnum); // This will cause a compilation error + return System.Enum.Parse(typeof(TestEnum), value); // This will work +} -The `typeof` operator can be used on a type parameter. The result is the `System.Type` object for the run-time type that was bound to the type parameter. The `typeof` operator can also be used on a constructed type or an unbound generic type ([§8.4.4](8-types.md#844-bound-and-unbound-types)). The `System.Type` object for an unbound generic type is not the same as the `System.Type` object of the instance type ([§15.3.2](15-classes.md#1532-the-instance-type)). The instance type is always a closed constructed type at run-time so its `System.Type` object depends on the run-time type arguments in use. The unbound generic type, on the other hand, has no type arguments, and yields the same `System.Type` object regardless of runtime type arguments. +public enum TestEnum +{ + Value1 = 1, + Value2 = 2, + Value3 = 3 +} -> *Example*: The example -> -> -> ```csharp -> class X -> { -> public static void PrintTypes() -> { -> Type[] t = -> { -> typeof(int), -> typeof(System.Int32), -> typeof(string), -> typeof(double[]), -> typeof(void), -> typeof(T), -> typeof(X), -> typeof(X>), -> typeof(X<>) -> }; -> for (int i = 0; i < t.Length; i++) -> { -> Runtime.Log(t[i]); -> } -> } -> } -> -> class Test : SmartContract.Framework.SmartContract -> { -> public static void Test() -> { -> X.PrintTypes(); -> } -> } -> ``` -> -> produces the following output: -> -> ```console -> System.Int32 -> System.Int32 -> System.String -> System.Double[] -> System.Void -> System.Int32 -> X`1[System.Int32] -> X`1[X`1[System.Int32]] -> X`1[T] -> ``` -> -> Note that `int` and `System.Int32` are the same type. -> The result of `typeof(X<>)` does not depend on the type argument but the result of `typeof(X)` does. -> -> *end example* +``` ### 12.8.18 The sizeof operator diff --git a/docs/csharp/13-statements.md b/docs/csharp/13-statements.md index 11e4e3908..c86594b31 100644 --- a/docs/csharp/13-statements.md +++ b/docs/csharp/13-statements.md @@ -2,9 +2,9 @@ ## 13.1 General -C# provides a variety of statements. +Neo C# provides a variety of statements. -> *Note*: Most of these statements will be familiar to developers who have programmed in C and C++. *end note* +> *Note*: Most of these statements will be the same as in C#. *end note* ```ANTLR statement @@ -1090,7 +1090,7 @@ The `foreach` statement enumerates the elements of a collection, executing an em ```ANTLR foreach_statement - : 'foreach' '(' ref_kind? local_variable_type identifier 'in' + : 'foreach' '(' ref_kind? local_variable_type identifier 'in' expression ')' embedded_statement ; ``` @@ -1238,7 +1238,7 @@ The body of the `finally` block is constructed according to the following steps: ``` - Otherwise, the `finally` clause is expanded to: - + ```csharp finally { @@ -1680,14 +1680,14 @@ If an exception is thrown during execution of a `finally` block, and is not caug > { > Runtime.Log("Catch"); > } -> +> > bool ExceptionFilter(Exception ex) > { > Runtime.Log("Filter"); > return true; > } > } -> +> > static void Method() > { > try diff --git a/docs/csharp/22-attributes.md b/docs/csharp/22-attributes.md index 0d78d9641..3e43de68e 100644 --- a/docs/csharp/22-attributes.md +++ b/docs/csharp/22-attributes.md @@ -149,7 +149,6 @@ The types of positional and named parameters for an attribute class are limited - One of the following types: `bool`, `byte`, `char`, `int`, `long`, `sbyte`, `short`, `string`, `uint`, `ulong`, `ushort`. - The type `object`. -- The type `System.Type`. - Enum types. - Single-dimensional arrays of the above types. - A constructor argument or public field that does not have one of these types, shall not be used as a positional or named parameter in an attribute specification. @@ -389,7 +388,7 @@ An expression `E` is an *attribute_argument_expression* if all of the following - The type of `E` is an attribute parameter type ([§22.2.4](22-attributes.md#2224-attribute-parameter-types)). - At compile-time, the value of `E` can be resolved to one of the following: - A constant value. - - A `System.Type` object obtained using a *typeof_expression* ([§12.8.17](12-expressions.md#12817-the-typeof-operator)) specifying a non-generic type, a closed constructed type ([§8.4.3](8-types.md#843-open-and-closed-types)), or an unbound generic type ([§8.4.4](8-types.md#844-bound-and-unbound-types)), but not an open type ([§8.4.3](8-types.md#843-open-and-closed-types)). + - A closed constructed type ([§8.4.3](8-types.md#843-open-and-closed-types)), or an unbound generic type ([§8.4.4](8-types.md#844-bound-and-unbound-types)), but not an open type ([§8.4.3](8-types.md#843-open-and-closed-types)). - A single-dimensional array of *attribute_argument_expression*s. > *Example*: diff --git a/docs/csharp/introduction.md b/docs/csharp/introduction.md index a018d473b..82af11de4 100644 --- a/docs/csharp/introduction.md +++ b/docs/csharp/introduction.md @@ -4,11 +4,12 @@ This specification is based on a subset of the standard C# language, specificall Neo C# is designed to provide developers with a familiar and powerful language for creating smart contracts, while ensuring compatibility with the NEO blockchain's execution environment. As such, it includes several important differences from standard C#: -- NEO C# does not support floating-point types, to ensure deterministic execution across all nodes in the blockchain network. +- Neo C# does not support floating-point types, to ensure deterministic execution across all nodes in the blockchain network. - File operations are not supported, as smart contracts operate in a sandboxed environment without direct access to the file system. - Threading is not available, as smart contracts are designed to execute as single-threaded, atomic operations. - Unsafe code and pointer operations are not supported, to maintain security and prevent direct memory manipulation. - The `dynamic` keyword is not supported, all types must be clearly defined with a type known at compile time, to ensure security and predictability in smart contract execution. +- Reflection is not supported in neo C#, as it could introduce unpredictability and security risks in the smart contract environment. - Certain other features of standard C# may be limited or unavailable to maintain security and predictability in the blockchain context. The goals of neo C# include: @@ -21,7 +22,7 @@ The goals of neo C# include: While NEO C# is based on the C# language, it is important for developers to be aware of its specific limitations and optimizations for blockchain use. This specification aims to provide a clear and comprehensive guide to writing smart contracts using NEO C#, highlighting both its capabilities and constraints within the NEO ecosystem. -The name C# is pronounced "C Sharp". And in this specification, when we refer to C#, we mean neo C#. +The name C# is pronounced "C Sharp". And in this specification, when we refer to C# in this specification, we mean neo C#. The name C# is written as the LATIN CAPITAL LETTER C (U+0043) followed by the NUMBER SIGN # (U+0023). diff --git a/docs/csharp/standard-library.md b/docs/csharp/standard-library.md index a16f05bcd..808b986d0 100644 --- a/docs/csharp/standard-library.md +++ b/docs/csharp/standard-library.md @@ -19,7 +19,7 @@ It is expected that a conforming C# implementation will supply a significantly **End of informative text.** -## C.2 Standard Library Types defined in ISO/IEC 23271 +## C.2 Standard Library Types defined in ISO/IEC 23271 and Supported by Neo C# > *Note:* Some `struct` types below have the `readonly` modifier. This modifier was not available > when ISO/IEC 23271 was released, but is required for conforming implementations of this specification. *end note* @@ -97,7 +97,6 @@ namespace System public readonly struct Boolean { } public readonly struct Byte { } public readonly struct Char { } - public readonly struct Decimal { } public abstract class Delegate { } public class DivideByZeroException : ArithmeticException @@ -107,7 +106,6 @@ namespace System public DivideByZeroException(string message, Exception innerException); } - public readonly struct Double { } public abstract class Enum : ValueType { @@ -157,8 +155,8 @@ namespace System { public NotSupportedException(); public NotSupportedException(string message); - public NotSupportedException(string message, - Exception innerException); + public NotSupportedException(string message, + Exception innerException); } public struct Nullable @@ -338,25 +336,12 @@ namespace System.Diagnostics } } -namespace System.Reflection -{ - public abstract class MemberInfo - { - protected MemberInfo(); - } -} - namespace System.Runtime.CompilerServices { public sealed class IndexerNameAttribute : Attribute { public IndexerNameAttribute(String indexerName); } - - public static class Unsafe - { - public static ref T NullRef(); - } } ``` @@ -964,7 +949,6 @@ The following library types are referenced in this specification. The full names - `global::System.StackOverflowException` - `global::System.String` - `global::System.SystemException` -- `global::System.Type` - `global::System.TypeInitializationException` - `global::System.UInt16` - `global::System.UInt32` diff --git a/src/Neo.SmartContract.Analyzer/AnalyzerReleases.Unshipped.md b/src/Neo.SmartContract.Analyzer/AnalyzerReleases.Unshipped.md index 98696f2c2..4daf45bbd 100644 --- a/src/Neo.SmartContract.Analyzer/AnalyzerReleases.Unshipped.md +++ b/src/Neo.SmartContract.Analyzer/AnalyzerReleases.Unshipped.md @@ -24,3 +24,4 @@ NC4021 | Usage | Warning | SupportedStandardsAnalyzer NC4022 | Usage | Warning | BigIntegerUsingUsageAnalyzer NC4023 | Usage | Error | StaticFieldInitializationAnalyzer NC4024 | Usage | Error | MultipleCatchBlockAnalyzer +NC4025 | Method | Error | EnumMethodsUsageAnalyzer