国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

AOT漫談:C# AOT 的泛型,序列化,反射問題

開發(fā) 前端
在 .NET AOT 編程中,難免會在 泛型,序列化,以及反射的問題上糾結和反復糾錯嘗試,這篇我們就來好好聊一聊相關的處理方案。

一、背景

講故事

在 .NET AOT 編程中,難免會在 泛型,序列化,以及反射的問題上糾結和反復糾錯嘗試,這篇我們就來好好聊一聊相關的處理方案。

二、常見問題解決

1. 泛型問題

研究過泛型的朋友應該都知道,從開放類型上產下來的封閉類型往往會有單獨的 MethodTable,并共用 EEClass,對于值類型的泛型相當于是不同的個體,如果在 AOT Compiler 的過程中沒有單獨產生這樣的個體信息,自然在運行時就會報錯,這么說可能有點懵,舉一個簡單的例子。

internal class Program
    {
        static void Main(string[] args)
        {
            var type = Type.GetType(Console.ReadLine());

            try
            {
                var mylist = typeof(List<>).MakeGenericType(type);

                var instance = Activator.CreateInstance(mylist);
                int count = (int)mylist.GetProperty("Count").GetValue(instance);
                Console.WriteLine(count);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
    }

    public class Location
    {
    }

圖片

從上圖看直接拋了一個異常,主要原因在于 Location 被踢出了依賴圖,那怎么辦呢?很顯然可以直接 new List<Location> 到依賴圖中,但在代碼中直接new是非常具有侵入性的操作,那如何讓侵入性更小呢?自然就是借助 AOT 獨有的 rd (Runtime Directives) 這種xml機制,具體可參見:https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/rd-xml-format.md

rd機制非常強大,大概如下:

1)可以指定程序集,類型,方法作為編譯圖的根節(jié)點使用,和 ILLink 有部分融合。2)可以手工的進行泛型初始化,也可以將泛型下的某方法作為根節(jié)點使用。3)為Marshal和Delegate提供Pinvoke支持。

在 ilc 源碼中是用 compilationRoots 來承載rd過去的根節(jié)點,可以一探究竟。

foreach (var rdXmlFilePath in Get(_command.RdXmlFilePaths))
{
    compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath));
}

有了這些知識就可以在 rd.xml 中實例化 List<Location> 了,參考如下:

<?xml versinotallow="1.0" encoding="utf-8" ?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
 <Application>
  <Assembly Name="Example_21_1">
   <Type Name="System.Collections.Generic.List`1[[Example_21_1.Location,Example_21_1]]" Dynamic="Required All" />
  </Assembly>
 </Application>
</Directives>

同時在 csproj 做一下引入即可。

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>net8.0</TargetFramework>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <PublishAot>true</PublishAot>
  <InvariantGlobalization>true</InvariantGlobalization>
 </PropertyGroup>
 <ItemGroup>
  <RdXmlFile Include="rd.xml" />
 </ItemGroup>
</Project>

執(zhí)行之后如下,要注意一點的是 Dynamic="Required All" 它可以把 List<Location> 下的所有方法和字段都注入到了依賴圖中,比如下圖中的 Count 屬性方法。

圖片圖片

2. 序列化問題

序列化會涉及到大量的反射,而反射又需要得到大量的元數據支持,所以很多第三方的Json序列化無法實現,不過官方提供的Json序列化借助于 SourceGenerator 將原來 dll 中的元數據遷移到了硬編碼中,從而變相的實現了AOT的Json序列化,參考代碼如下:

namespace Example_21_1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var person = new Person()
            {
                Name = "john",
                Age = 30,
                BirthDate = new DateTime(1993, 5, 15),
                Gender = "Mail"
            };

            var jsonString = JsonSerializer.Serialize(person,
                                            SourceGenerationContext.Default.Person);

            Console.WriteLine(jsonString);
            Console.ReadLine();
        }
    }
}

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Person))]
internal partial class SourceGenerationContext : JsonSerializerContext { }

public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
    public string Gender { get; set; }
}

當用 VS 調試的時候,你會發(fā)現多了一個 SourceGenerationContext.Person.g.cs 文件,并且用 properties 數組承載了 Person 的元數據,截圖如下:

圖片圖片

3. 反射問題

反射其實也是一個比較糾結的問題,簡單的反射AOT編譯器能夠輕松推測,但稍微需要上下文關聯(lián)的就搞不定了,畢竟涉及到上下文關聯(lián)需要大量的算力,而目前的AOT編譯本身就比較慢了,所以暫時沒有做支持,相信后續(xù)的版本會有所改進吧,接下來舉一個例子演示下。

internal class Program
    {
        static void Main(string[] args)
        {
            Invoke(typeof(Person));

            Console.ReadLine();
        }

        static void Invoke(Type type)
        {
            var props = type.GetProperties();

            foreach (var prop in props)
            {
                Console.WriteLine(prop);
            }
        }
    }

    public class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
        public string Gender { get; set; }
    }

這段代碼在 AOT中是提取不出屬性的,因為 Invoke(typeof(Person)); 和 type.GetProperties 之間隔了一個 Type type 參數,雖然我們肉眼能知道這個代碼的意圖,但 ilc 的深度優(yōu)先它不知道你需要 Person中的什么,所以它只保留了 Person 本身,如果你想直面觀測的話,可以這樣做:

  • 將 <PublishAot>true</PublishAot> 改成 <PublishTrimmed>true</PublishTrimmed>
  • 使用 dotnet publish 發(fā)布。
  • 使用ILSPY觀測。

截圖如下,可以看到 Person 空空如也。

圖片圖片

有了這個底子就比較簡單了,為了讓 Person 保留屬性,可以傻乎乎的用 DynamicallyAccessedMembers 來告訴AOT我到底想要什么,比如 PublicProperties 就是所有的屬性,當然也可以設置為 ALL。

static void Invoke([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type)
        {
            var props = type.GetProperties();

            foreach (var prop in props)
            {
                Console.WriteLine(prop);
            }
        }

如果要想侵入性更小的話,可以使用 TrimmerRootDescriptor 這種外來的 xml 進行更高級別的定制,比如我不想要 Gender 字段 ,具體參考官方鏈接:https://github.com/dotnet/runtime/blob/main/docs/tools/illink/data-formats.md#xml-examples

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>net8.0</TargetFramework>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <PublishAot>true</PublishAot>
  <InvariantGlobalization>true</InvariantGlobalization>
  <IlcGenerateMapFile>true</IlcGenerateMapFile>
 </PropertyGroup>
 <ItemGroup>
  <TrimmerRootDescriptor Include="link.xml" />
 </ItemGroup>
</Project>

然后就是 xml 配置。

<?xml versinotallow="1.0" encoding="utf-8" ?>
<linker>
 <assembly fullname="Example_21_1">
  <type fullname="Example_21_1.Person">
   <property signature="System.Int32 Age" />
   <property signature="System.String Name" />
   <property signature="System.DateTime BirthDate" />
  </type>
 </assembly>
</linker>

從下圖看,一切都是那么完美。

圖片圖片

責任編輯:武曉燕 來源: 一線碼農聊技術
相關推薦

2024-10-11 14:42:59

2024-10-14 13:01:33

AOTcpu符號

2009-08-24 17:14:08

C#序列化

2021-01-20 08:24:38

序列化內存對象

2009-08-06 11:16:25

C#序列化和反序列化

2009-08-25 14:24:36

C#序列化和反序列化

2011-06-01 14:50:48

2024-05-06 00:00:00

C#序列化技術

2009-08-25 14:43:26

C#序列化和反序列化

2009-08-24 10:07:57

C#泛型處理

2009-08-26 18:02:05

C#泛型問題

2009-08-24 16:19:42

C# 泛型方法

2011-06-08 10:06:32

C#

2009-09-09 15:54:48

C# XML序列化

2009-08-25 14:59:39

C# XML序列化應用

2009-09-09 16:53:49

C# XmlSeria序列化

2009-09-09 16:30:59

C# BinaryFo

2009-08-25 15:15:08

C#對象序列化應用

2009-06-24 10:25:25

C#泛型

2009-08-24 14:43:35

C# 泛型
點贊
收藏

51CTO技術棧公眾號

西西人体一区二区| 国产成人午夜| 精品免费国产二区三区| 精品国产三级a∨在线| 欧美午夜视频| 欧洲精品在线视频| 黄色漫画在线免费观看| 亚洲成a人片在线观看中文| 中文视频在线| 欧美日韩精品欧美日韩精品一综合| 免费超碰在线| 亚洲精品一区二区三区香蕉 | 怡红院亚洲色图| 亚洲国产精品免费视频| 亚洲图片制服诱惑| 在线人成日本视频| 日韩精品极品毛片系列视频| 在线看的毛片| 国外色69视频在线观看| 久久久久久欧美精品色一二三四| 尤物视频在线观看| 日本韩国欧美一区二区三区| 黄网站在线播放| 日韩欧美一级片| 天天影视综合色| 亚洲激情自拍偷拍| 亚洲第一av| 国产成人一区二区三区电影| 国产精品亚洲午夜一区二区三区| 捆绑紧缚一区二区三区在线观看| 色综合91久久精品中文字幕| 国产字幕视频一区二区| 日本在线观看免费视频| www.豆豆成人网.com| 精品国产电影一区二区| av在线下载| 久久精品人人做人人爽| 免费观看久久av| 翡翠波斯猫1977年美国| 精品一二线国产| 99视频免费| 日韩欧美视频一区| 中文字幕视频精品一区二区三区| 国产一区二区在线网站| 亚洲免费视频成人| 内射国产内射夫妻免费频道| 亚洲综合图片区| 午夜精品久久久久久久99水蜜桃| 久久免费福利| 欧美伦理片在线观看| 97久久久免费福利网址| 成人午夜电影小说| 日韩电影免费看| 伊人网在线免费| av成人在线观看| 欧洲亚洲女同hd| 国产九九视频一区二区三区| 在线观看视频污| 91福利视频网| 91免费视频网址| 国产乱码在线| 97免费在线视频| 97久久精品人人做人人爽| 成人在线高清视频| 3d动漫啪啪精品一区二区免费| 99久久精品99国产精品| 24小时免费看片在线观看| 欧美一区二区视频在线观看2020 | 午夜一区二区三区在线观看| 日韩亚洲一区在线| 爱福利视频一区| 国产精品不卡| 免费看的国产视频网站| 操日韩av在线电影| 极品少妇xxxx精品少妇偷拍| 小草av在线播放| 精品免费视频123区| 一个色综合网站| 99久久www免费| 岛国最新视频免费在线观看| 国产精品播放| 91精品福利在线一区二区三区| 亚洲经典三级| 91制片厂毛片| 日韩美女视频免费看| 午夜欧美巨大性欧美巨大| 久久久久久国产免费| 日韩一区二区高清| 亚洲日本护士毛茸茸| 日本v片在线高清不卡在线观看| 免费观看不卡av| 天堂√8在线中文| 水莓100在线视频| 91国偷自产一区二区三区观看| 国产精品久久久久久久久久久久久久久 | 在线播放麻豆| 国产精品av免费| 国产精品444| 日韩午夜激情视频| 综合久久久久久久| 亚洲91av| 国产精品嫩草99a| 欧美日本免费| 成人写真视频| 狠狠做六月爱婷婷综合aⅴ| 国产一区一区| 亚洲综合影视| 国产视频福利在线| 中文字幕网av| 无码aⅴ精品一区二区三区浪潮| 亚洲综合一区二区精品导航| 天天做夜夜做人人爱精品 | 日韩大胆成人| 成人影音在线| 在线免费观看h| 国产又黄又爽免费视频| 国产精品久久久久久久久久免费 | 香蕉视频免费在线| 波多野结衣激情| 亚洲7777| 青青草原国产免费| 午夜欧美一区二区三区免费观看| 久久精品日韩| 日本在线视频一区| 国产精品一二三在线观看| 欧美一级中文字幕| 精品久久国产老人久久综合| 欧美99久久| 精品一区二区三区在线观看视频| 求av网址在线观看| 男人插女人欧美| www黄色av| 正在播放91九色| 深夜福利成人| 亚洲精品视频一二三| 97在线日本国产| 国内精品一区二区三区四区| 欧美大片在线看| 久久亚洲影音av资源网| 久久成人精品电影| 亚洲欧美国产一区二区三区| 草久在线视频| 免费成人深夜夜行视频| 亚洲一卡二卡| www.夜夜爽| 黄网站在线免费看| 四虎国产精品免费久久| 国产一区二区三区91| 日本不卡在线视频| 亚洲欧洲国产专区| 欧美年轻男男videosbes| 强制捆绑调教一区二区| 欧美特大特白屁股xxxx| 三妻四妾完整版在线观看电视剧 | 中文久久乱码一区二区| 国产精品视频在线看| 国产精品乱码人人做人人爱 | 男女激情网站| 在线观看黄色av| 欧美精品日日操| 欧美不卡一区二区| 中文成人av在线| 欧美伊人久久大香线蕉综合69| 亚洲美女性生活视频| 精品一区二区三区国产| 成人拍拍拍免费视频网站| 男人的天堂av高清在线| 在线视频超级| 亚洲国产综合在线看不卡| www.av精品| 欧美性猛交xxxxx免费看| 中文国产字幕在线观看| 国产精品高清一区二区| 久久影视三级福利片| 久久久久久毛片免费看 | 日本精品在线中文字幕| av在线日韩| 最新国产精品精品视频| 一区三区在线欧| 男人天堂欧美日韩| www午夜视频| 麻豆精品一区二区av白丝在线| 国产91在线播放精品| 一级黄色特级片| 91美女片黄在线观| 欧美成人剧情片在线观看| 久久久久欧美| 午夜亚洲成人| 2023国产精华国产精品| 在线看片福利| 欧美成人免费高清视频| 中文在线а√在线| 麻豆网站在线看| 台湾佬综合网| 福利电影一区二区三区| 亚洲婷婷综合久久一本伊一区 | 精品成人av一区| 99视频有精品| 日韩一区精品视频| 国产视频一区二区在线播放|