推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

结构体局部静态本地函数总结(不再是只定义)

   2023-06-16 网络整理佚名1900
核心提示:静态本地函数总结对象,并使用它们在运行时索引/切片集合。在数组元素访问中使用类型作为参数,需要以下成员:要在数组元素访问表达式中使用的类型值,必须存在以下成员:,以避免对多维签名重载混合整数和索引的需求。具备内插表达式的项的结构如下所示:生成需要设置格式的结果的表达式。受表达式结果类型支持的格式字符串。有关更多信息,请参阅格式字符串组件。

--- 方法可以实现(不再只是定义)

  public interface MyInterface
    {
        public int Age { get; set; }
        void Method1(int age)
        {
            Console.WriteLine(age);
        }
    }

成员

public readonly struct Coords
  {
      public Coords(double x, double y)
        {
            X = x;
            Y = y;
        }
      public double X { get; set; }
      public double Y { get; set; }
      public override string ToString() => $"({X}, {Y})";
  }

---- 结构局部只读

public struct Coords{
      public double X { get; set; }
      public double Y { get; set; }
      private int counter;
      public  int Counter
        {
            readonly get => counter;
            set => counter = value;
        }
     
      public override string ToString() => $"({X}, {Y})";
      public readonly double Sum()
        {
            
            return X + Y;
        }
  }

静态局部函数总结

支持禁止从封闭范围捕获状态的本机函数。

详细设计

声明的局部函数无法从封闭范围捕获状态。 因此,封闭范围内的局部变量、参数和 this 在局部函数中是不可用的。

本地函数不能隐式或显式或通过引用引用实例成员 this base。

局部函数可以引用封闭范围内的成员。

static int z = 0;
 int InnerMethod(){
    int y = 5;
    int x = 7;
       
    return LocalStaticFunction(x, y);
    //静态本地函数
    static int LocalStaticFunction(int left, int right) {
                return z + left + right;
    }
}

异步流

在 C# 8.0 之前,支持迭代器方法和异步方法,但不支持既是迭代器又是异步方法的方法。 我们应该通过允许 await 使用新的迭代器形式 async 来纠正这个问题,它将返回一个 or 而不是 or ,在 new 中使用 await 。 接口还用于启用异步清理。

新界面:、/

通常,任何清理资源的时间都是有用的,例如关闭文件(需要刷新)、注销回调以及提供一种了解注销何时完成的方法等。

namespace System
{
    public interface IAsyncDisposable
    {
        ValueTask DisposeAsync();
    }
}

和with一样,多次调用是可以接受的,第一次调用之后的调用应该被当作nops(意思是后面的调用都应该是nops),返回同步完成的任务(不需要是线程安全的,也不需要支持并发调用).

名称解释:nop 什么都不做

namespace System.Collections.Generic
{
    public interface IAsyncEnumerable
    {
        IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default);
    }
    public interface IAsyncEnumerator : IAsyncDisposable
    {
        ValueTask MoveNextAsync();
        T Current { get; }
    }
}

IAsyncEnumerator enumerator = enumerable.GetAsyncEnumerator();
try
{
    while (await enumerator.MoveNextAsync())
    {
        Use(enumerator.Current);
    }
}
finally { await enumerator.DisposeAsync(); }

static async void Main(string[] args) {
    IAsyncEnumerable asyncEnumerable = AsyncEnumerableTest();
    IAsyncEnumerator asyncEnumerator = asyncEnumerable.GetAsyncEnumerator();
    try{
       while (await asyncEnumerator.MoveNextAsync()) {
           Console.WriteLine(asyncEnumerator.Current);
        } 
    }
    finally { await asyncEnumerator.DisposeAsync(); }
}
## 异步迭代器,但await不能在这些迭代器的主体中使用
private static async IAsyncEnumerable AsyncEnumerableTest()
{
    await Task.Delay(100);
    yield return "001";
    yield return "002";
    yield return "003";
    yield return "004";
    yield return "005";
}

引入异步

要强制只考虑异步 API,请按如下方式插入 await:

await foreach (var i in enumerable)

var enumerable = ...; 
await foreach (T item in enumerable) {    ... } 
### 转换为的等效项:
var enumerable = ...;
var enumerator = enumerable.GetAsyncEnumerator();
try
{
    while (await enumerator.MoveNextAsync())
    {
       T item = enumerator.Current;
       ...
    }
}
finally
{
    await enumerator.DisposeAsync(); // omitted, along with the try/finally, if the enumerator doesn't expose DisposeAsync
}

这种基于模式的编译允许在所有等待中使用扩展方法

await foreach (T item in enumerable.ConfigureAwait(false))
{
   ...
}
###这将基于我们还将添加到 .NET 的类型,可能会 System.Threading.Tasks.Extensions.dll:

LINQ 添加异步方法

List list = new List();
            list.Add("001");
            list.Add("002");
            list.Add("003");
            list.Add("004");
            list.Select(AsyncMethod);
async ValueTask AsyncMethod(string item){
         await Task.Yield();
        return item + "-";
}

List list = new List();
            list.Add("001");
            list.Add("002");
            list.Add("003");
            list.Add("004");
            list.Select(async (item) =>
            {
                await Task.Yield();
                return item + "-";
            });

 public partial class Form1 : Form
    {
        CancellationTokenSource cancellationToken;
        public Form1()
        {
            InitializeComponent();
        }
        private async void button1_Click(object sender, EventArgs e)
        {
            cancellationToken = new CancellationTokenSource();
            CancellationToken token = cancellationToken.Token;
            IAsyncEnumerable enumerable = ReadIntAsync(token);
            await Task.Delay(3000);
            //设置要在循环访问时传递到 GetAsyncEnumerator(CancellationToken) 的 CancellationToken。
            //enumerable.WithCancellation(token);
            IAsyncEnumerator enumerator = enumerable.GetAsyncEnumerator();
            try
            {
                while (await enumerator.MoveNextAsync())
                {
                    Debug.WriteLine(enumerator.Current);
                }
            }
            catch (TaskCanceledException ex1)
            {
                Console.WriteLine(ex1.Message);
            }
            catch (OperationCanceledException ex2)
            {
                Console.WriteLine(ex2.Message);
            }
            finally
            {
                await enumerator.DisposeAsync();
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            cancellationToken = cancellationToken??new CancellationTokenSource();
            cancellationToken.Cancel();
        }
        
        
        private async IAsyncEnumerable ReadIntAsync([EnumeratorCancellation] CancellationToken _token)
        {
            try
            {
                for (int i = 0; i < 20; i++)
                {
                    //取消任务及其子级
                    if (_token.IsCancellationRequested)
                    {
                        _token.ThrowIfCancellationRequested();
                    }
                    await Task.Delay(200, _token);
                    yield return i;
                }
            }
            finally
            {
                Console.WriteLine("finally");
            }
        }
    }

索引和范围

此功能提供了两个新的运算符,允许构造 .Index 和 .Range 对象并在运行时使用它们对集合进行索引/切片。

namespace System
{
    public readonly struct Index
    {
        public Index(int value, bool fromEnd);
    }
}

要将 .Index 类型用作数组元素访问中的参数,需要以下成员:

int System.Index.GetOffset(int length);

int[] arr = new int[6] { 132, 67, 47, 58, 83, 100 };

索引 index = new Index(8, true);

- - 抵消

int = index.(arr.);

.Range 的 .. 语法需要 .Range 类型,以及以下一个或多个成员:

namespace System
{
    public readonly struct Range
    {
        public Range(System.Index start, System.Index end);
        public static Range StartAt(System.Index start);
        public static Range EndAt(System.Index end);
        public static Range All { get; }
    }
}

最后,对于要在数组元素访问表达式中使用的 .Range 类型的值,必须存在以下成员:

//System.Runtime.CompilerServices=> 意味着编译器一开始就可以编译
namespace System.Runtime.CompilerServices
{
    public static class RuntimeHelpers
    {
        public static T[] GetSubArray(T[] array, System.Range range);
    }
}

该语言引入了一个新的范围运算符 x..y。它是一个二元中缀运算符,它接受两个表达式

System.Range operator ..(Index start = 0, Index end = ^0);

.. 将运算符称为范围运算符

 public Index(int value, bool fromEnd);

运算符 ^ 等价于 Index(int value, bool )

例子:

int[] arr = new int[6] { 132, 67, 47, 58, 83,100};
//获取前三个元素 以某某作为截止
int[] vs1 = RuntimeHelpers.GetSubArray(arr, Range.EndAt(3));
//获取后三个元素 以某某作为开始
int[] vs2 = RuntimeHelpers.GetSubArray(arr, Range.StartAt(3));
Console.WriteLine(vs2);

 Range range1 = Range.StartAt(2);//从第三个元素开始 startIndex<=x

从尾部开始计算下标为真:= arr.-index;

新索引(索引,:真)。(数组。)

var array = new int[] { 1, 2, 3, 4, 5 };
var lastItem = array[^1];    // array[new Index(1, fromEnd: true)]
var slice1 = array[2..^3];    // array[new Range(2, new Index(3, fromEnd: true))]
var slice2 = array[..^3];     // array[Range.EndAt(new Index(3, fromEnd: true))]
var slice3 = array[2..];      // array[Range.StartAt(2)]
var slice4 = array[..];       // array[Range.All]

此外,.Index 应该从 .Int32 隐式转换,以避免需要混合整数和索引的多维签名重载。

这个新的优先级组低于一元运算符并大于乘法算术运算符

插入逐字字符串的增强功能 插入字符串的结构

要将字符串标识为内插字符串,请在字符串前面加上

和 " 之间不能有任何空格。要连接多个内插字符串,请将 $ 特殊字符添加到每个字符串文字。

带有插值表达式的项的结构如下:

 {pression>[,][:]}

元素描述

离子

产生需要格式化的结果的表达式。 null 的字符串表示形式是 .Empty。

一个常量表达式,如果值为正,则其字符串表示形式右对齐,如果值为负,则其字符串表示形式左对齐。 该值为字符串的长度,如果小于表达式的实际值,则按实际值长度计算。

表达式结果类型支持的格式字符串。 有关详细信息,请参阅格式字符串组件。

比如时间格式:MM/dd/yy H:mm:ss zzz

GUID 格式:N 或 D(参见下面的示例)|

Console.WriteLine($"|{"Left000"}|{"000Right"}|");
Console.WriteLine($"|{"Left",-7}|{"Right",7}|");
---输出结果:--
|Left000|000Right|
|Left   |  Right|
-----
Guid guid = Guid.NewGuid();
Console.WriteLine($"{guid:N}");

小破站:

颤音:

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
Powered By DESTOON