Pedoman pengkodian — MRTK2

Dokumen ini menguraikan prinsip dan konvensi pengkodian yang harus diikuti saat berkontribusi pada MRTK.


Filsafat

Ringkas dan berusahalah untuk kesederhanaan

Solusi paling sederhana sering kali yang terbaik. Ini adalah tujuan utama dari pedoman ini dan harus menjadi tujuan dari semua aktivitas pengkodian. Bagian dari menjadi sederhana adalah ringkas, dan konsisten dengan kode yang ada. Cobalah untuk menjaga kode Anda tetap sederhana.

Pembaca hanya boleh menemukan artefak yang memberikan informasi yang berguna. Misalnya, komentar yang mengembalikan apa yang jelas tidak memberikan informasi tambahan dan meningkatkan kebisingan terhadap rasio sinyal.

Jaga agar logika kode tetap sederhana. Perhatikan bahwa ini bukan pernyataan tentang menggunakan jumlah baris terkecil, meminimalkan ukuran nama pengidentifikasi atau gaya kurung kurawal, tetapi tentang mengurangi jumlah konsep dan memaksimalkan visibilitas baris tersebut melalui pola yang sudah dikenal.

Menghasilkan kode yang konsisten dan dapat dibaca

Keterbacaan kode berkorelasi dengan tingkat cacat yang rendah. Berusahalah untuk membuat kode yang mudah dibaca. Berusahalah untuk membuat kode yang memiliki logika sederhana dan menggunakan kembali komponen yang ada karena juga akan membantu memastikan kebenaran.

Semua detail kode yang Anda hasilkan penting, dari detail paling mendasar tentang kebenaran hingga gaya dan pemformatan yang konsisten. Jaga agar gaya pengkodian Anda tetap konsisten dengan apa yang sudah ada, meskipun gaya tersebut tidak cocok dengan preferensi Anda. Ini meningkatkan keterbacaan basis kode secara keseluruhan.

Mendukung konfigurasi komponen baik di editor maupun pada run-time

MRTK mendukung beragam pengguna - orang yang lebih suka mengonfigurasi komponen di editor Unity dan memuat prefab, dan orang-orang yang perlu membuat dan mengonfigurasi objek pada run-time.

Semua kode Anda harus berfungsi dengan KEDUANYA menambahkan komponen ke GameObject dalam adegan yang disimpan, dan dengan membuat instans komponen tersebut dalam kode. Pengujian harus mencakup kasus pengujian baik untuk membuat contoh prefab dan membuat instans, mengonfigurasi komponen saat runtime.

Play-in-editor adalah platform target pertama dan utama Anda

Play-In-Editor adalah cara tercepat untuk melakukan iterasi di Unity. Menyediakan cara bagi pelanggan kami untuk iterasi dengan cepat memungkinkan mereka untuk mengembangkan solusi dengan lebih cepat dan mencoba lebih banyak ide. Dengan kata lain, memaksimalkan kecepatan iterasi memberdayakan pelanggan kami untuk mencapai lebih banyak hal.

Buat semuanya berfungsi secara editor, lalu membuatnya berfungsi di platform lain. Tetap bekerja di editor. Sangat mudah untuk menambahkan platform baru ke Play-In-Editor. Sangat sulit untuk membuat Play-In-Editor berfungsi jika aplikasi Anda hanya berfungsi di perangkat.

Tambahkan bidang publik baru, properti, metode, dan bidang privat berseri dengan hati-hati

Setiap kali Anda menambahkan metode publik, bidang, properti, metode tersebut menjadi bagian dari permukaan API publik MRTK. Bidang privat yang ditandai dengan [SerializeField] juga mengekspos bidang ke editor dan merupakan bagian dari permukaan API publik. Orang lain mungkin menggunakan metode publik tersebut, mengonfigurasi prefab kustom dengan bidang publik Anda, dan mengambil dependensi pada metode tersebut.

Anggota publik baru harus diperiksa dengan hati-hati. Setiap bidang publik perlu dipertahankan di masa depan. Ingat bahwa jika jenis bidang publik (atau bidang privat berseri) berubah atau dihapus dari MonoBehaviour, yang dapat merusak orang lain. Bidang harus terlebih dahulu ditolak untuk rilis, dan kode untuk memigrasikan perubahan bagi orang-orang yang telah mengambil dependensi perlu disediakan.

Memprioritaskan pengujian penulisan

MRTK adalah proyek komunitas, yang dimodifikasi oleh beragam kontributor. Kontributor ini mungkin tidak mengetahui detail perbaikan/fitur bug Anda, dan secara tidak sengaja merusak fitur Anda. MRTK menjalankan pengujian integrasi berkelanjutan sebelum menyelesaikan setiap permintaan pull. Perubahan yang menghentikan pengujian tidak dapat dicek masuk. Oleh karena itu, pengujian adalah cara terbaik untuk memastikan bahwa orang lain tidak merusak fitur Anda.

Ketika Anda memperbaiki bug, tulis pengujian untuk memastikannya tidak mengalami kemunculan di masa mendatang. Jika menambahkan fitur, tulis pengujian yang memverifikasi bahwa fitur Anda berfungsi. Ini diperlukan untuk semua fitur UX kecuali fitur eksperimental.

Konvensi C# Coding

Header informasi lisensi skrip

Semua karyawan Microsoft yang berkontribusi file baru harus menambahkan header Lisensi standar berikut di bagian atas file baru apa pun, persis seperti yang ditunjukkan di bawah ini:

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

Header ringkasan fungsi /metode

Semua kelas publik, struktur, enum, fungsi, properti, bidang yang diposting ke MRTK harus digambarkan dengan tujuan dan penggunaannya, persis seperti yang ditunjukkan di bawah ini:

/// <summary>
/// The Controller definition defines the Controller as defined by the SDK / Unity.
/// </summary>
public struct Controller
{
    /// <summary>
    /// The ID assigned to the Controller
    /// </summary>
    public string ID;
}

Ini memastikan dokumentasi dihasilkan dan disebarluaskan dengan benar untuk semua kelas, metode, dan properti.

File skrip apa pun yang dikirimkan tanpa tag ringkasan yang tepat akan ditolak.

Aturan namespace MRTK

Mixed Reality Toolkit menggunakan model namespace layanan berbasis fitur, di mana semua namespace dasar dimulai dengan "Microsoft.MixedReality.Toolkit". Secara umum, Anda tidak perlu menentukan lapisan toolkit (misalnya: Core, Providers, Services) di namespace Anda.

Namespace yang ditentukan saat ini adalah:

  • Microsoft.MixedReality.Toolkit
  • Microsoft.MixedReality.Toolkit.Boundary
  • Microsoft.MixedReality.Toolkit.Diagnostics
  • Microsoft.MixedReality.Toolkit.Editor
  • Microsoft.MixedReality.Toolkit.Input
  • Microsoft.MixedReality.Toolkit.SpatialAwareness
  • Microsoft.MixedReality.Toolkit.Teleport
  • Microsoft.MixedReality.Toolkit.Utilities

Untuk namespace dengan sejumlah besar jenis, dapat diterima untuk membuat sejumlah terbatas sub-namespace untuk membantu dalam cakupan penggunaan.

Menghilangkan namespace layanan untuk antarmuka, kelas, atau jenis data akan menyebabkan perubahan Anda diblokir.

Menambahkan skrip MonoBehaviour baru

Saat menambahkan skrip MonoBehaviour baru dengan permintaan pull, pastikan AddComponentMenu atribut diterapkan ke semua file yang berlaku. Ini memastikan komponen mudah ditemukan di editor di bawah tombol Tambahkan Komponen . Bendera atribut tidak diperlukan jika komponen tidak dapat muncul di editor seperti kelas abstrak.

Dalam contoh di bawah ini, Paket di sini harus diisi dengan lokasi paket komponen. Jika menempatkan item di folder MRTK/SDK , maka paket akan menjadi SDK.

[AddComponentMenu("Scripts/MRTK/{Package here}/MyNewComponent")]
public class MyNewComponent : MonoBehaviour

Menambahkan skrip inspektur Unity baru

Secara umum, cobalah untuk menghindari pembuatan skrip inspektur kustom untuk komponen MRTK. Ini menambahkan overhead tambahan dan manajemen basis kode yang dapat ditangani oleh mesin Unity.

Jika kelas inspektur diperlukan, coba gunakan Unity DrawDefaultInspector(). Ini lagi-lagi menyederhanakan kelas inspektur dan meninggalkan banyak pekerjaan untuk Unity.

public override void OnInspectorGUI()
{
    // Do some custom calculations or checks
    // ....
    DrawDefaultInspector();
}

Jika penyajian kustom diperlukan di kelas inspektur, coba gunakan SerializedProperty dan EditorGUILayout.PropertyField. Ini akan memastikan Unity menangani render prefab berlapis dan nilai yang dimodifikasi dengan benar.

Jika EditorGUILayout.PropertyField tidak dapat digunakan karena persyaratan dalam logika kustom, pastikan semua penggunaan dibungkus di sekitar EditorGUI.PropertyScope. Ini akan memastikan Unity merender inspektur dengan benar untuk prefab berlapis dan nilai yang dimodifikasi dengan properti yang diberikan.

Selain itu, cobalah untuk menghias kelas pemeriksa kustom dengan CanEditMultipleObjects. Tag ini memastikan beberapa objek dengan komponen ini dalam adegan dapat dipilih dan dimodifikasi bersama-sama. Setiap kelas inspektur baru harus menguji bahwa kode mereka berfungsi dalam situasi ini di tempat kejadian.

    // Example inspector class demonstrating usage of SerializedProperty & EditorGUILayout.PropertyField
    // as well as use of EditorGUI.PropertyScope for custom property logic
    [CustomEditor(typeof(MyComponent))]
    public class MyComponentInspector : UnityEditor.Editor
    {
        private SerializedProperty myProperty;
        private SerializedProperty handedness;

        protected virtual void OnEnable()
        {
            myProperty = serializedObject.FindProperty("myProperty");
            handedness = serializedObject.FindProperty("handedness");
        }

        public override void OnInspectorGUI()
        {
            EditorGUILayout.PropertyField(destroyOnSourceLost);

            Rect position = EditorGUILayout.GetControlRect();
            var label = new GUIContent(handedness.displayName);
            using (new EditorGUI.PropertyScope(position, label, handedness))
            {
                var currentHandedness = (Handedness)handedness.enumValueIndex;

                handedness.enumValueIndex = (int)(Handedness)EditorGUI.EnumPopup(
                    position,
                    label,
                    currentHandedness,
                    (value) => {
                        // This function is executed by Unity to determine if a possible enum value
                        // is valid for selection in the editor view
                        // In this case, only Handedness.Left and Handedness.Right can be selected
                        return (Handedness)value == Handedness.Left
                        || (Handedness)value == Handedness.Right;
                    });
            }
        }
    }

Menambahkan ScriptableObjects baru

Saat menambahkan skrip ScriptableObject baru, pastikan CreateAssetMenu atribut diterapkan ke semua file yang berlaku. Ini memastikan komponen mudah ditemukan di editor melalui menu pembuatan aset. Bendera atribut tidak diperlukan jika komponen tidak dapat muncul di editor seperti kelas abstrak.

Dalam contoh di bawah ini, Subfolder harus diisi dengan subfolder MRTK, jika berlaku. Jika menempatkan item di folder MRTK/Providers , maka paket akan menjadi Penyedia. Jika menempatkan item di folder MRTK/Core , atur ini ke "Profil".

Dalam contoh di bawah ini, myNewService | MyNewProvider harus diisi dengan nama kelas baru Anda, jika berlaku. Jika menempatkan item di folder MixedRealityToolkit , biarkan string ini keluar.

[CreateAssetMenu(fileName = "MyNewProfile", menuName = "Mixed Reality Toolkit/{Subfolder}/{MyNewService | MyNewProvider}/MyNewProfile")]
public class MyNewProfile : ScriptableObject

Pengelogan

Saat menambahkan fitur baru atau memperbarui fitur yang ada, pertimbangkan untuk menambahkan log DebugUtilities.LogVerbose ke kode menarik yang mungkin berguna untuk penelusuran kesalahan di masa mendatang. Ada tradeoff di sini antara menambahkan pengelogan dan kebisingan tambahan dan pengelogan tidak cukup (yang membuat diagnosis sulit).

Contoh menarik di mana pengelogan berguna (bersama dengan payload yang menarik):

DebugUtilities.LogVerboseFormat("RaiseSourceDetected: Source ID: {0}, Source Type: {1}", source.SourceId, source.SourceType);

Jenis pengelogan ini dapat membantu menangkap masalah seperti https://github.com/microsoft/MixedRealityToolkit-Unity/issues/8016, yang disebabkan oleh sumber yang tidak cocok yang terdeteksi dan peristiwa sumber hilang.

Hindari menambahkan log untuk data dan peristiwa yang terjadi pada setiap bingkai - idealnya pengelogan harus mencakup peristiwa "menarik" yang didorong oleh input pengguna yang berbeda (yaitu "klik" oleh pengguna dan serangkaian perubahan dan peristiwa yang berasal dari yang menarik untuk dicatat). Status yang sedang berlangsung dari "pengguna masih memegang gerakan" yang dicatat setiap bingkai tidak menarik dan akan membanjiri log.

Perhatikan bahwa pengelogan verbose ini tidak diaktifkan secara default (harus diaktifkan dalam pengaturan Sistem Diagnostik)

Spasi vs tab

Pastikan untuk menggunakan 4 spasi alih-alih tab saat berkontribusi pada proyek ini.

Jarak

Jangan tambahkan spasi tambahan antara tanda kurung siku dan tanda kurung:

Jangan

private Foo()
{
    int[ ] var = new int [ 9 ];
    Vector2 vector = new Vector2 ( 0f, 10f );
}

Lakukan

private Foo()
{
    int[] var = new int[9];
    Vector2 vector = new Vector2(0f, 10f);
}

Konvensi penamaan

Selalu gunakan PascalCase untuk properti. Gunakan camelCase untuk sebagian besar bidang, kecuali gunakan PascalCase untuk static readonly bidang dan const . Satu-satunya pengecualian untuk ini adalah untuk struktur data yang mengharuskan bidang diserialisasikan oleh JsonUtility.

Jangan

public string myProperty; // <- Starts with a lowercase letter
private string MyField; // <- Starts with an uppercase letter

Lakukan

public string MyProperty;
protected string MyProperty;
private static readonly string MyField;
private string myField;

Pengubah akses

Selalu nyatakan pengubah akses untuk semua bidang, properti, dan metode.

  • Semua Metode UNITY API harus private secara default, kecuali Anda perlu mengambil alihnya di kelas turunan. Dalam hal protected ini harus digunakan.

  • Bidang harus privateselalu , dengan public atau protected pengaktor properti.

  • Gunakan anggota bertubuh ekspresi dan properti otomatis jika memungkinkan

Jangan

// protected field should be private
protected int myVariable = 0;

// property should have protected setter
public int MyVariable => myVariable;

// No public / private access modifiers
void Foo() { }
void Bar() { }

Lakukan

public int MyVariable { get; protected set; } = 0;

private void Foo() { }
public void Bar() { }
protected virtual void FooBar() { }

Gunakan kurung kurawal

Selalu gunakan kurung kurawal setelah setiap blok pernyataan, dan letakkan di baris berikutnya.

Jangan

private Foo()
{
    if (Bar==null) // <- missing braces surrounding if action
        DoThing();
    else
        DoTheOtherThing();
}

Jangan

private Foo() { // <- Open bracket on same line
    if (Bar==null) DoThing(); <- if action on same line with no surrounding brackets
    else DoTheOtherThing();
}

Lakukan

private Foo()
{
    if (Bar==true)
    {
        DoThing();
    }
    else
    {
        DoTheOtherThing();
    }
}

Kelas publik, struktur, dan enum semuanya harus masuk ke dalam file mereka sendiri

Jika kelas, struct, atau enum dapat dibuat privat maka tidak apa-apa untuk disertakan dalam file yang sama. Ini menghindari masalah kompilasi dengan Unity dan memastikan bahwa abstraksi kode yang tepat terjadi, itu juga mengurangi konflik dan melanggar perubahan ketika kode perlu berubah.

Jangan

public class MyClass
{
    public struct MyStruct() { }
    public enum MyEnumType() { }
    public class MyNestedClass() { }
}

Lakukan

 // Private references for use inside the class only
public class MyClass
{
    private struct MyStruct() { }
    private enum MyEnumType() { }
    private class MyNestedClass() { }
}

Lakukan

MyStruct.cs

// Public Struct / Enum definitions for use in your class.  Try to make them generic for reuse.
public struct MyStruct
{
    public string Var1;
    public string Var2;
}

MyEnumType.cs

public enum MuEnumType
{
    Value1,
    Value2 // <- note, no "," on last value to denote end of list.
}

MyClass.cs

public class MyClass
{
    private MyStruct myStructReference;
    private MyEnumType myEnumReference;
}

Menginisialisasi enum

Untuk memastikan semua enum diinisialisasi dengan benar mulai dari 0, .NET memberi Anda pintasan rapi untuk menginisialisasi enum secara otomatis hanya dengan menambahkan nilai (starter) pertama. (misalnya Nilai 1 = 0 Nilai yang tersisa tidak diperlukan)

Jangan

public enum Value
{
    Value1, <- no initializer
    Value2,
    Value3
}

Lakukan

public enum ValueType
{
    Value1 = 0,
    Value2,
    Value3
}

Enum pesanan untuk ekstensi yang sesuai

Sangat penting bahwa jika Enum kemungkinan akan diperpanjang di masa depan, untuk memesan default di bagian atas Enum, ini memastikan indeks Enum tidak terpengaruh dengan penambahan baru.

Jangan

public enum SDKType
{
    WindowsMR,
    OpenVR,
    OpenXR,
    None, <- default value not at start
    Other <- anonymous value left to end of enum
}

Lakukan

/// <summary>
/// The SDKType lists the VR SDKs that are supported by the MRTK
/// Initially, this lists proposed SDKs, not all may be implemented at this time (please see ReleaseNotes for more details)
/// </summary>
public enum SDKType
{
    /// <summary>
    /// No specified type or Standalone / non-VR type
    /// </summary>
    None = 0,
    /// <summary>
    /// Undefined SDK.
    /// </summary>
    Other,
    /// <summary>
    /// The Windows 10 Mixed reality SDK provided by the Universal Windows Platform (UWP), for Immersive MR headsets and HoloLens.
    /// </summary>
    WindowsMR,
    /// <summary>
    /// The OpenVR platform provided by Unity (does not support the downloadable SteamVR SDK).
    /// </summary>
    OpenVR,
    /// <summary>
    /// The OpenXR platform. SDK to be determined once released.
    /// </summary>
    OpenXR
}

Meninjau penggunaan enum untuk bitfields

Jika ada kemungkinan bagi enum untuk memerlukan beberapa status sebagai nilai, misalnya Handedness = Kiri & Kanan. Maka Enum perlu didekorasi dengan benar dengan BitFlags untuk memungkinkannya digunakan dengan benar

File Handedness.cs memiliki implementasi konkret untuk ini

Jangan

public enum Handedness
{
    None,
    Left,
    Right
}

Lakukan

[Flags]
public enum Handedness
{
    None = 0 << 0,
    Left = 1 << 0,
    Right = 1 << 1,
    Both = Left | Right
}

Jalur file yang dikodekan secara permanen

Saat membuat jalur file string, dan secara khusus menulis jalur string yang dikodekan secara permanen, lakukan hal berikut:

  1. Gunakan API C#jika Path memungkinkan seperti Path.Combine atau Path.GetFullPath.
  2. Gunakan / atau Path.DirectorySeparatorChar alih-alih \ atau \\.

Langkah-langkah ini memastikan bahwa MRTK berfungsi pada sistem berbasis Windows dan Unix.

Jangan

private const string FilePath = "MyPath\\to\\a\\file.txt";
private const string OtherFilePath = "MyPath\to\a\file.txt";

string filePath = myVarRootPath + myRelativePath;

Lakukan

private const string FilePath = "MyPath/to/a/file.txt";
private const string OtherFilePath = "folder{Path.DirectorySeparatorChar}file.txt";

string filePath = Path.Combine(myVarRootPath,myRelativePath);

// Path.GetFullPath() will return the full length path of provided with correct system directory separators
string cleanedFilePath = Path.GetFullPath(unknownSourceFilePath);

Praktik terbaik, termasuk rekomendasi Unity

Beberapa platform target proyek ini perlu mempertimbangkan performa. Dengan mengingat hal ini, selalu berhati-hatilah saat mengalokasikan memori dalam kode yang sering disebut dalam perulangan atau algoritma pembaruan yang ketat.

Enkapsulasi

Selalu gunakan bidang privat dan properti publik jika akses ke bidang diperlukan dari luar kelas atau struktur. Pastikan untuk menemukan bersama bidang privat dan properti publik. Ini membuatnya lebih mudah dilihat, sekilas, apa yang mendukung properti dan bahwa bidang dapat dimodifikasi oleh skrip.

Catatan

Satu-satunya pengecualian untuk ini adalah untuk struktur data yang mengharuskan bidang diserialisasikan oleh JsonUtility, di mana kelas data diperlukan untuk memiliki semua bidang publik agar serialisasi berfungsi.

Jangan

private float myValue1;
private float myValue2;

public float MyValue1
{
    get{ return myValue1; }
    set{ myValue1 = value }
}

public float MyValue2
{
    get{ return myValue2; }
    set{ myValue2 = value }
}

Lakukan

// Enable field to be configurable in the editor and available externally to other scripts (field is correctly serialized in Unity)
[SerializeField]
[ToolTip("If using a tooltip, the text should match the public property's summary documentation, if appropriate.")]
private float myValue; // <- Notice we co-located the backing field above our corresponding property.

/// <summary>
/// If using a tooltip, the text should match the public property's summary documentation, if appropriate.
/// </summary>
public float MyValue
{
    get => myValue;
    set => myValue = value;
}

/// <summary>
/// Getter/Setters not wrapping a value directly should contain documentation comments just as public functions would
/// </summary>
public float AbsMyValue
{
    get
    {
        if (MyValue < 0)
        {
            return -MyValue;
        }

        return MyValue
    }
}

Nilai cache dan serialisasikan di adegan/prefab jika memungkinkan

Dengan mengingat HoloLens, yang terbaik adalah mengoptimalkan referensi performa dan cache dalam adegan atau prefab untuk membatasi alokasi memori runtime.

Jangan

void Update()
{
    gameObject.GetComponent<Renderer>().Foo(Bar);
}

Lakukan

[SerializeField] // To enable setting the reference in the inspector.
private Renderer myRenderer;

private void Awake()
{
    // If you didn't set it in the inspector, then we cache it on awake.
    if (myRenderer == null)
    {
        myRenderer = gameObject.GetComponent<Renderer>();
    }
}

private void Update()
{
    myRenderer.Foo(Bar);
}

Referensi cache ke bahan, jangan panggil ".material" setiap kali

Unity akan membuat bahan baru setiap kali Anda menggunakan ".material", yang akan menyebabkan kebocoran memori jika tidak dibersihkan dengan benar.

Jangan

public class MyClass
{
    void Update()
    {
        Material myMaterial = GetComponent<Renderer>().material;
        myMaterial.SetColor("_Color", Color.White);
    }
}

Lakukan

// Private references for use inside the class only
public class MyClass
{
    private Material cachedMaterial;

    private void Awake()
    {
        cachedMaterial = GetComponent<Renderer>().material;
    }

    void Update()
    {
        cachedMaterial.SetColor("_Color", Color.White);
    }

    private void OnDestroy()
    {
        Destroy(cachedMaterial);
    }
}

Catatan

Atau, gunakan properti "SharedMaterial" Unity yang tidak membuat materi baru setiap kali dirujuk.

Gunakan kompilasi dependen platform untuk memastikan Toolkit tidak akan merusak build di platform lain

  • Gunakan WINDOWS_UWP untuk menggunakan API khusus UWP, non-Unity. Ini akan mencegah mereka mencoba menjalankan di Editor atau pada platform yang tidak didukung. Ini setara dengan UNITY_WSA && !UNITY_EDITOR dan harus digunakan untuk mendukung.
  • Gunakan UNITY_WSA untuk menggunakan API Unity khusus UWP, seperti UnityEngine.XR.WSA namespace layanan. Ini akan berjalan di Editor ketika platform diatur ke UWP, serta di aplikasi UWP bawaan.

Bagan ini dapat membantu Anda memutuskan mana yang #if akan digunakan, tergantung pada kasus penggunaan Anda dan pengaturan build yang Anda harapkan.

Platform UWP IL2CPP UWP .NET Editor
UNITY_EDITOR FALSE FALSE True
UNITY_WSA True True True
WINDOWS_UWP True True Salah
UNITY_WSA && !UNITY_EDITOR True True Salah
ENABLE_WINMD_SUPPORT True True FALSE
NETFX_CORE FALSE True FALSE

Pilih DateTime.UtcNow daripada DateTime.Now

DateTime.UtcNow lebih cepat daripada DateTime.Now. Dalam penyelidikan performa sebelumnya, kami telah menemukan bahwa menggunakan DateTime.Now menambahkan overhead yang signifikan terutama saat digunakan dalam perulangan Update(). Yang lain mengalami masalah yang sama.

Lebih suka menggunakan DateTime.UtcNow kecuali Anda benar-benar memerlukan waktu yang dilokalkan (alasan yang sah mungkin Anda ingin menunjukkan waktu saat ini di zona waktu pengguna). Jika Anda berurusan dengan waktu relatif (yaitu delta antara beberapa pembaruan terakhir dan sekarang), yang terbaik adalah menggunakan DateTime.UtcNow untuk menghindari overhead melakukan konversi zona waktu.

Konvensi pengkodean PowerShell

Subset basis kode MRTK menggunakan PowerShell untuk infrastruktur alur dan berbagai skrip dan utilitas. Kode PowerShell baru harus mengikuti gaya PoshCode.

Lihat juga

Konvensi pengkodian C# dari MSDN