亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

自從.NET 5 發(fā)布以來,許多人都在問它對.NET Standard 意味著什么,想知道它是不是還能吸引主流開發(fā)人員的興趣。

在本文中,我將介紹.NET 5 是如何改善代碼共享并替代.NET Standard 的。同時,我還將介紹一些仍然需要.NET Standard 的情況。

TL;DR

.NET 5 將是一個具有一組統(tǒng)一特性和 API 的單一產(chǎn)品,可用于 windows 桌面應(yīng)用、跨平臺移動應(yīng)用、控制臺應(yīng)用、云服務(wù)和網(wǎng)站。

為更好地反映這一點(diǎn),我們更新了目標(biāo)框架名稱(TFM):

  • net5.0。這適用于運(yùn)行在所有平臺上的代碼。它合并并替換了netcoreApp和netstandard名稱。這個 TFM 總體上只包括跨平臺工作的技術(shù)(除了一些特例,就像我們在.NET Standard 中所做的那樣)。
  • net5.0-windows(以及之后的net6.0-Android和net6.0-IOS)。這些 TFM 代表特定于 OS 的.NET 5 風(fēng)味,其中包括net5.0加上特定于 OS 的特性。

我們不會再發(fā)布.NET Standard 的新版本了,但是.NET 5 和所有將來的版本都會繼續(xù)支持.NET Standard 2.1 和更早版本。你應(yīng)該將net5.0(及以后的版本)視為未來共享代碼的基礎(chǔ)。

由于net5.0是所有這些新 TFM 的共享基礎(chǔ),因此這意味著運(yùn)行時、庫和新的語言特性將圍繞這個版本號來運(yùn)作。例如,為了使用 C# 9,你需要使用net5.0或net5.0-windows。

你的目標(biāo)應(yīng)該是什么

.NET 5 和將來所有的版本都會一直支持.NET Standard 2.1 和更早版本。從.NET Standard 目標(biāo)切換到.NET 5 的唯一理由是可以訪問更多的運(yùn)行時特性、語言特性或 API。因此,你可以將.NET 5 視為.NET Standard 的 vNext。

新代碼呢?你還是應(yīng)該從.NET Standard 2.0 開始還是應(yīng)該直接進(jìn)入.NET 5?這要看具體情況。

  • 應(yīng)用組件。如果你使用庫將應(yīng)用程序分解為多個組件,我的建議是使用netX.Y,其中X.Y是應(yīng)用程序(或多個應(yīng)用程序)目標(biāo)的最低.NET。為簡單起見,你可能希望組成應(yīng)用程序的所有項目都位于同一版本的.NET 上,因為這樣以來,你就可以在所有地方都獲得相同的 BCL 特性。
  • 可重用的庫。如果你要構(gòu)建計劃在 NuGet 上發(fā)布的可重用庫,則需要考慮覆蓋率和可用特性集之間的權(quán)衡。.NET Standard 2.0 是.NET Framework 支持的.NET Standard 的最高版本,因此它將為你提供最大的覆蓋范圍,同時還為你提供了相當(dāng)大的特性集。我們通常建議你不要以.NET Standard 1.x 為目標(biāo),因為麻煩事太多了。如果你不需要支持.NET Framework,則可以使用.NET Standard 2.1 或.NET 5。大多數(shù)代碼都可以跳過.NET Standard 2.1,直接轉(zhuǎn)到.NET 5。

那到底該怎么辦?我的建議是,廣泛使用的庫最終將同時將.NET Standard 2.0 和.NET 5 作為目標(biāo):支持.NET Standard 2.0 可為你提供最大的支持范圍,而支持.NET 5 可確保你能為客戶提供.NET 5 上最新的平臺特性。

在幾年內(nèi),可重用庫的選項僅涉及netX.Y的版本號,這基本上就是為.NET 構(gòu)建庫的標(biāo)準(zhǔn)途徑——通常來說,你會希望支持某些較舊的版本,以確保獲得最大的采用率。

總結(jié)一下:

  • 使用netstandard 2.0在.NET Framework 和其他所有平臺之間共享代碼。
  • 使用netstandard 2.1在 Mono、Xamarin 和.NET Core 3.x 之間共享代碼。
  • 使用net5.0為將來的項目進(jìn)行代碼共享。

.NET 5 如何解決.NET Standard 存在的問題

.NET Standard 讓開發(fā)人員可輕松創(chuàng)建適用于所有.NET 平臺的庫。但是,.NET Standard 仍然存在三個問題:

  1. 它的版本更替很慢,這意味著你無法輕松使用最新特性。
  2. 它需要一個解碼器環(huán)才能將版本映射到.NET 實(shí)現(xiàn)。
  3. 它公開了特定于平臺的特性,這意味著你無法靜態(tài)驗證代碼是否真正可移植。

讓我們看看.NET 5 是如何解決這三個問題的。

問題 1:.NET Standard 版本更新緩慢

.NET Standard 是.NET 平臺尚未在實(shí)現(xiàn)級別融合的時候設(shè)計的。這使開發(fā)人員很難編寫需要在不同環(huán)境中運(yùn)行的代碼,因為不同的負(fù)載使用了不同的.NET 實(shí)現(xiàn)。

.NET Standard 的目標(biāo)是統(tǒng)一基類庫(BCL)的特性集,以便你可以編寫可在任何地方運(yùn)行的庫。這對我們很有幫助:.NET Standard 在前 1000 個軟件包中得到了 77%以上的支持。而且,如果我們查看 NuGet.org 上最近 6 個月中更新的所有軟件包,則采用率是 58%。

支持.NET Standard 的包:

.NET Standard停止更新,它將何去何從?

 

但是單獨(dú)標(biāo)準(zhǔn)化 API 集會有代價。每當(dāng)我們添加新的 API 時都需要協(xié)調(diào)。.NET 開源社區(qū)(包括.NET 團(tuán)隊)通過提供新的語言特性、可用性改進(jìn)、新的跨領(lǐng)域特性(例如Span<T>)或支持新的數(shù)據(jù)格式或網(wǎng)絡(luò)協(xié)議,以在 BCL 中不斷創(chuàng)新前進(jìn)。

盡管我們可以將新類型作為 NuGet 包來提供,但我們不能以這種方式在現(xiàn)有類型上提供新的 API。因此從一般意義上講,BCL 中的創(chuàng)新需要交付新版本的.NET Standard。

在.NET Standard 2.0 之前,這并不是什么大問題,因為我們僅對現(xiàn)有的 API 進(jìn)行了標(biāo)準(zhǔn)化。但是在.NET Standard 2.1 中,我們對全新的 API 進(jìn)行了標(biāo)準(zhǔn)化,因此我們遇到了很多麻煩。

這種摩擦從何而來?

.NET Standard 是所有.NET 實(shí)現(xiàn)都必須支持的 API 集,因此它有一個編輯準(zhǔn)則,即所有 API 必須由.NET Standard 審查委員會審查。該委員會由.NET 平臺實(shí)現(xiàn)者和.NET 社區(qū)的代表組成,目標(biāo)是僅標(biāo)準(zhǔn)化我們可以在所有當(dāng)前和將來的.NET 平臺中真正實(shí)現(xiàn)的 API。這些檢查是必要的,因為.NET 堆棧的實(shí)現(xiàn)方式不同,約束條件也不同。

我們預(yù)測到了這種摩擦,這就是為什么我們之前提到.NET Standard 只會標(biāo)準(zhǔn)化至少在一個.NET 實(shí)現(xiàn)中提供 API 的原因。一開始這似乎挺合理,但隨后,你就意識到.NET Standard 不能頻繁發(fā)布新版本。因此,如果某個特性錯過了某個特定版本,則可能需要等上幾年才能發(fā)布,甚至可能需要更長時間才能等到這個版本的.NET Standard 得到廣泛支持。

對某些特性來說,我們感到機(jī)會成本太高了,因此我們采取了非常規(guī)的行動來標(biāo)準(zhǔn)化尚未交付的 API(例如IAsyncEnumerable<T>)。但是,對所有特性都這么做,實(shí)在是太昂貴了,這就是為什么許多特性仍然錯過了.NET Standard 2.1 的原因(例如新的硬件內(nèi)部函數(shù))。

但是,如果只有一個代碼庫呢?如果這個代碼庫需要支持現(xiàn)在讓.NET 實(shí)現(xiàn)分裂的所有選項,例如同時支持即時(JIT)編譯和提前(AOT)編譯,又會怎么樣?

從一開始,我們就將所有這些選項都納入了特性設(shè)計,而不是事后才考慮。在這種情況下,標(biāo)準(zhǔn)化的 API 集在構(gòu)造上就是通用的 API 集。一個特性被實(shí)現(xiàn)后,由于代碼庫是共享的,因此這個特性立刻就能被所有人使用。

問題 2:.NET Standard 需要解碼環(huán)

將 API 集與對應(yīng)的實(shí)現(xiàn)分離,不僅僅是減緩了 API 的可用性,這也意味著我們需要將.NET Standard 版本映射到它們的實(shí)現(xiàn)上。隨著時間的推移,我需要向越來越多的人解釋這種關(guān)系,于是發(fā)現(xiàn)這種看似簡單的想法其實(shí)非常復(fù)雜。我們盡了最大的努力來簡化它,但畢竟這是固有的復(fù)雜性,因為 API 集和實(shí)現(xiàn)是分開獨(dú)立提供的。

我們統(tǒng)一了 .NET 平臺,在它們下面又增加了一個合成平臺,代表了通用的 API 集。這幅受 XKCD 啟發(fā)的漫畫就畫得很明白:

.NET Standard停止更新,它將何去何從?

 

.NET 5 要做的就是真正在框架中合并一些部分,從而解決這個問題:.NET 5 提供了一個統(tǒng)一的實(shí)現(xiàn),所有部分都在相同的基礎(chǔ)上構(gòu)建,并因此獲得相同的 API 形狀和版本號。

問題 3:.NET Standard 公開了特定平臺 API

在設(shè)計.NET Standard 時,我們必須做出務(wù)實(shí)的妥協(xié),以免對庫生態(tài)系統(tǒng)造成過大的破壞。換句話說,我們必須包括一些只適用于Windows 的API(例如文件系統(tǒng)ACL、注冊表、WMI 等)。展望未來,我們將避免在 net5.0、net6.0和以后的版本中添加特定于平臺的 API。但我們無法預(yù)測未來,例如,借助 Blazor WebAssembly,我們最近添加了一個新環(huán)境,可以在其中運(yùn)行.NET,可瀏覽器的沙箱中不支持某些跨平臺 API(例如線程或進(jìn)程控制)。

很多人抱怨說,這類 API 就像“地雷”一樣——代碼編譯沒有錯誤,因此似乎可以移植到任何平臺,但是在沒有針對給定 API 實(shí)現(xiàn)的平臺上運(yùn)行時就會出現(xiàn)運(yùn)行時錯誤。

從.NET 5 開始,我們將默認(rèn)隨附帶有 SDK 的分析器和代碼修復(fù)程序,其中包括平臺兼容性分析器,該分析器可檢測到你準(zhǔn)備運(yùn)行的平臺上不支持哪些API,并報告相應(yīng)的意外使用情況。此特性替代了 Microsoft.DotNet.Analyzers.Compatibility NuGet 包。

首先,讓我們看一下 Windows 專屬的 API。

處理特定于 Windows 的 API

創(chuàng)建以 net5.0 為目標(biāo)的項目時,可以引用 Microsoft.Win32.Registry 包。但當(dāng)你開始使用它時,會收到以下警告:

private static string GetLoggingDirectory()
{    
     using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SoftwareFabrikam"))
     { 
          if (key?.GetValue("LoggingDirectoryPath") is string configuredPath)
              return configuredPath;
     }   
  string exePath = Process.GetCurrentProcess().MainModule.FileName; 
  string folder = Path.GetDirectoryName(exePath); 
  return Path.Combine(folder, "Logging");
}
CA1416: 'RegistryKey.OpenSubKey(string)' is supported on 'windows'
CA1416: 'Registry.CurrentUser' is supported on 'windows'
CA1416: 'RegistryKey.GetValue(string?)' is supported on 'windows'

關(guān)于如何解決這些警告,你有三個選項:

  1. 守護(hù)調(diào)用。你可以使用OperatingSystem.IsWindows(),在調(diào)用 API 之前檢查你是否在 Windows 上運(yùn)行。
  2. 將調(diào)用標(biāo)記為 Windows 專屬。在某些情況下,可以通過[SupportedOSPlatform("windows")]將調(diào)用成員標(biāo)記為平臺專屬。
  3. 刪除代碼。通常這不是你想要的,因為這意味著 Windows 用戶使用你的代碼時會損失一些內(nèi)容,但是對于存在跨平臺替代方案的情況,你最好放棄那些平臺專屬的代碼。例如,可以使用 XML 配置文件來替代注冊表。
  4. 禁止警告。你當(dāng)然可以通過.editorconfig或#pragmawarningdisable來作弊,簡單地禁用警告。但是,在使用特定于平臺的 API 時,你應(yīng)該選擇選項(1)和(2)。

為了守護(hù)調(diào)用,請在 System.OperatingSystem 類上使用新的靜態(tài)方法,例如:

private static string GetLoggingDirectory()
{   
    if (OperatingSystem.IsWindows())  
    {  
        using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SoftwareFabrikam"))  
        {
             if (key?.GetValue("LoggingDirectoryPath") is string configuredPath) 
               return configuredPath; 
        }
    }   
  string exePath = Process.GetCurrentProcess().MainModule.FileName;   
  string folder = Path.GetDirectoryName(exePath);   
  return Path.Combine(folder, "Logging");
}

將代碼標(biāo)記為 Windows 專屬,請應(yīng)用新的SupportedOSPlatform屬性:

[SupportedOSPlatform("windows")]
private static string GetLoggingDirectory()
{ 
    using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SoftwareFabrikam"))
    {  
        if (key?.GetValue("LoggingDirectoryPath") is string configuredPath)
          return configuredPath;
    } 
  string exePath = Process.GetCurrentProcess().MainModule.FileName; 
  string folder = Path.GetDirectoryName(exePath);   
  return Path.Combine(folder, "Logging");
}

在這兩種情況下,使用注冊表的警告都會消失。

關(guān)鍵區(qū)別在于,在第二個示例中,分析器現(xiàn)在將針對GetLoggingDirectory()的調(diào)用站點(diǎn)發(fā)出警告,因為它現(xiàn)在被視為 Windows 特定的 API。換句話說,你將進(jìn)行平臺檢查的要求轉(zhuǎn)發(fā)給了調(diào)用者。

[SupportedOSPlatform]屬性可以應(yīng)用于成員、類型或程序集級別。BCL 本身也使用此屬性。例如,程序集Microsoft.Win32.Registry應(yīng)用了此屬性,所以分析器能先知道注冊表是 Windows 特定的 API。

請注意,如果你以net5.0-windows為目標(biāo),此屬性將自動應(yīng)用于你的程序集。這意味著從net5.0-windows使用 Windows 專屬的 API 永遠(yuǎn)不會產(chǎn)生任何警告,因為你的整個程序集都被視為 Windows 專屬的。

處理 Blazor WebAssembly 中不支持的 API

Blazor WebAssembly 項目在瀏覽器沙箱中運(yùn)行,這限制了你可以使用的 API。例如,盡管線程和進(jìn)程創(chuàng)建都是跨平臺的 API,但我們無法使這些 API 在 Blazor WebAssembly 中運(yùn)行,這意味著它們會拋出PlatformNotSupportedException警告。我們已經(jīng)用[UnsupportedOSPlatform("browser")]標(biāo)記了這些 API。

假設(shè),你將GetLoggingDirectory()方法復(fù)制并粘貼到一個 Blazor WebAssembly 應(yīng)用程序中。

private static string GetLoggingDirectory()
{
    //... 
    string exePath = Process.GetCurrentProcess().MainModule.FileName; 
    string folder = Path.GetDirectoryName(exePath);   
    return Path.Combine(folder, "Logging");
}

你會收到以下警告:

CA1416 'Process.GetCurrentProcess()' is unsupported on 'browser'
CA1416 'Process.MainModule' is unsupported on 'browser'

為了處理這些警告,你的選項和處理 Windows 特定的 API 時基本相同。
你可以守護(hù)調(diào)用

private static string GetLoggingDirectory()
{   
   //... 
   if (!OperatingSystem.IsBrowser()) 
   {       
     string exePath = Process.GetCurrentProcess().MainModule.FileName;      
     string folder = Path.GetDirectoryName(exePath);  
     return Path.Combine(folder, "Logging");  
   }   
  else  
  {       
    return string.Empty;  
  }
}

或者,你可以將成員標(biāo)記為 Blazor WebAssembly 不支持的成員:

[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{  
  //...  
  string exePath = Process.GetCurrentProcess().MainModule.FileName;   
  string folder = Path.GetDirectoryName(exePath);  
  return Path.Combine(folder, "Logging");
}

由于瀏覽器沙箱的限制非常嚴(yán)格,因此不能預(yù)期所有類庫和 NuGet 包都能在 Blazor WebAssembly 中工作。此外,絕大多數(shù)庫也不一定能在 Blazor WebAssembly 中運(yùn)行。

因此,目標(biāo)為net5.0的常規(guī)類庫不會看到 Blazor WebAssembly 不支持的 API 警告。你必須通過在項目文件中添加項,來顯式聲明你打算在 Blazor WebAssembly 中支持你的項目:

<Project Sdk="Microsoft.NET.Sdk">   
  
  <PropertyGroup>   
     <TargetFramework>net5.0</TargetFramework> 
 </PropertyGroup>  

<ItemGroup>   
       <SupportedPlatform Include="browser" />  
 </ItemGroup>  

</Project>

如果你要構(gòu)建一個 Blazor WebAssembly 應(yīng)用程序,則不必這樣做,因為Microsoft.NET.Sdk.BlazorWebAssembly SDK 會自動執(zhí)行此操作。

.NET 5 作為.NET Standard 和.NET Core 的組合

.NET 5 及其后續(xù)版本將是一個單一代碼庫,它支持桌面應(yīng)用、移動應(yīng)用、云服務(wù)、網(wǎng)站以及未來.NET 將會運(yùn)行的任何環(huán)境。

你可能會認(rèn)為“等等,這聽起來不錯,但是如果有人想創(chuàng)建一個全新的實(shí)現(xiàn)該怎么辦”。這也是可以的。但實(shí)際上沒有人會從頭開始。這樣的實(shí)現(xiàn)很可能是當(dāng)前代碼庫( dotnet/runtime )的分支。例如,Tizen(三星用于智能設(shè)備的平臺)使用了一個經(jīng)過少量改動的.NET Core,并且在頂層使用了一個三星定制的應(yīng)用模型。

分叉保留了合并關(guān)系,維護(hù)人員可以從不受其更改影響的 BCL 創(chuàng)新中受益,從而繼續(xù)從 dotnet/runtime 倉庫中拉取新更改。這與 linux 發(fā)行版的機(jī)制非常相似。

當(dāng)然,在某些情況下,你可能想創(chuàng)建一種非常不同的.NET“類別”,例如在沒有當(dāng)前 BCL 的情況下最小化運(yùn)行時。但這意味著它無論如何都無法利用現(xiàn)有的.NET 庫生態(tài)系統(tǒng),也就是說,它也不會實(shí)現(xiàn).NET Standard。我們對這個方向總體來說并不感興趣,但是.NET Standard 和.NET Core 的融合并不能阻止這一點(diǎn),也不會為其增加障礙。

.NET 版本控制

作為庫作者,你可能想知道.NET 5 何時才能得到廣泛支持。展望未來,我們將在每年 11 月發(fā)布.NET,每隔一年將發(fā)布一個長期支持(LTS)版本。

.NET 5 將于 2020 年 11 月發(fā)布,.NET 6 將于 2021 年 11 月發(fā)布,是 LTS 版。我們定下了這個固定的時間表,以便大家更輕松地安排更新計劃(如果你是應(yīng)用開發(fā)人員),和預(yù)測對.NET 版本的支持需求(如果你是庫開發(fā)人員)。

由于.NET Core 能夠并行安裝,因此新版本的采用速度相當(dāng)快,其中 LTS 版本最為流行。實(shí)際上,.NET Core3.1 是有史以來普及最快的.NET 版本。

.NET Standard停止更新,它將何去何從?

.NET 5 時間表

可以預(yù)計每次交付時,我們都會一并更新所有框架名稱。例如,計劃可能是這個樣子:

.NET Standard停止更新,它將何去何從?

 

換句話說,你基本上可以指望:無論我們在 BCL 中所做的創(chuàng)新如何,無論它們運(yùn)行在哪個平臺上,你都將能在所有應(yīng)用模型中使用它。這也意味著,只要運(yùn)行最新版本的.NET,就始終可以在所有應(yīng)用模型中使用為最新的net框架提供的庫。

這種模式消除了.NET Standard 版本控制的復(fù)雜性,因為每次發(fā)布新版時,你都可以假定所有平臺都將立即且完全支持新版本。我們還使用前綴命名約定來鞏固這一承諾。

.NET 的新版本可能會增加對其他平臺的支持。例如,我們將為.NET 6 添加對 Android 和 iOS 的支持。相反,我們可能會停止支持不再流行的平臺。.NET 6 中就沒有net5.0-someoldos目標(biāo)框架。我們沒有移除某個平臺的計劃,但是這種模式下存在這種可能性。這會是一件大事,提前無法預(yù)料,而且會提前很長時間宣布。這與.NET Standard 使用的模式相同,例如,Windows Phone 已經(jīng)無法運(yùn)行更高版本的.NET Standard 了。

為什么沒有 WebAssembly 的 TFM

我們最初考慮為 WebAssembly 添加 TFM,例如net5.0-wasm。我們出于以下原因決定不這樣做:

  • WebAssembly 更像是指令集(例如 x86 或 x64),而非操作系統(tǒng)。而且,我們通常不會在不同的架構(gòu)之間提供不同的 API。
  • 瀏覽器沙箱中的 WebAssembly 執(zhí)行模型是一個重大創(chuàng)新,但我們認(rèn)為僅將其建模為一個運(yùn)行時檢查更有意義。與檢查 Windows 和 Linux 的方式類似,你可以使用 OperatingSystem 類型。由于這與指令集無關(guān),因此該方法稱為IsBrowser()而不是IsWebAssembly()。
  • WebAssembly 有運(yùn)行時標(biāo)識符( RID ),稱為browser和browser-wasm。它們允許包作者以瀏覽器中的 WebAssembly 為目標(biāo)時部署不同的二進(jìn)制文件。這對于需要事先編譯為 Web 程序集的原生代碼特別有用。

如上所述,我們標(biāo)記了瀏覽器沙箱中不支持的 API,例如System.Diagnostics.Process。如果你是從瀏覽器應(yīng)用中使用這些 API,則會收到警告,告知你不支持該 API。

總結(jié)

net5.0適用于在各種平臺上運(yùn)行的代碼。它合并并替換了netcoreapp和netstandard名稱。我們還有特定于平臺的框架,例如net5.0-windows(以及后來的net6.0-android和net6.0-ios)。

由于標(biāo)準(zhǔn)與其實(shí)現(xiàn)之間沒有區(qū)別,因此你可以比.NET Standard 更快地利用新特性。而且,由于采用了命名約定,你就能輕松判斷誰可以使用給定的庫,而無需查閱.NET Standard 版本表。

.NET Standard 2.1 將是.NET Standard 的最后版本,而.NET 5 和所有將來的版本將繼續(xù)支持.NET Standard 2.1 和更早版本。你應(yīng)該將 net5.0(及以后的版本)視為共享代碼的基礎(chǔ)。

原文鏈接:

https://devblogs.microsoft.com/dotnet/the-future-of-net-standard/

分享到:
標(biāo)簽:NET
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定