Delen via


Richtlijnen voor codering — MRTK2

In dit document worden codeerprincipes en -conventies beschreven die moeten worden gevolgd bij het bijdragen aan MRTK.


Filosofie

Wees beknopt en streven naar eenvoud

De eenvoudigste oplossing is vaak de beste. Dit is een overschrijvend doel van deze richtlijnen en moet het doel zijn van alle codeeractiviteiten. Een deel van het eenvoudig zijn is beknopt zijn en consistent zijn met bestaande code. Probeer uw code eenvoudig te houden.

Lezers mogen alleen artefacten tegenkomen die nuttige informatie bieden. Opmerkingen die bijvoorbeeld opnieuw aangeven wat duidelijk is, geven geen extra informatie en verhogen de ruis-signaalverhouding.

Houd codelogica eenvoudig. Houd er rekening mee dat dit geen instructie is over het gebruik van het minste aantal regels, het minimaliseren van de grootte van id-namen of accoladestijl, maar over het verminderen van het aantal concepten en het maximaliseren van de zichtbaarheid van deze concepten via vertrouwde patronen.

Consistente, leesbare code produceren

Leesbaarheid van code is gecorreleerd met lage defectpercentages. Probeer code te maken die gemakkelijk te lezen is. Probeer code te maken die eenvoudige logica bevat en bestaande onderdelen opnieuw gebruikt, omdat dit ook helpt om de juistheid te garanderen.

Alle details van de code die u produceert, zijn van belang, van de meest elementaire details van juistheid tot consistente stijl en opmaak. Houd uw coderingsstijl consistent met wat er al bestaat, zelfs als deze niet overeenkomt met uw voorkeur. Dit verhoogt de leesbaarheid van de algehele codebasis.

Ondersteuning voor het configureren van onderdelen in de editor en tijdens runtime

MRTK ondersteunt een diverse set gebruikers: personen die liever onderdelen configureren in de Unity-editor en prefabs laden, en personen die tijdens runtime objecten moeten instantiëren en configureren.

Al uw code moet werken door zowel een onderdeel toe te voegen aan een GameObject in een opgeslagen scène als door dat onderdeel in code te instantiëren. Tests moeten een testcase bevatten voor zowel het instantiëren van prefabs als het instantiëren van het onderdeel tijdens runtime.

Play-in-editor is uw eerste en primaire doelplatform

Play-In-Editor is de snelste manier om te herhalen in Unity. Door onze klanten manieren te bieden om snel te herhalen, kunnen ze sneller oplossingen ontwikkelen en meer ideeën uitproberen. Met andere woorden, het maximaliseren van de snelheid van iteratie stelt onze klanten in staat om meer te bereiken.

Zorg ervoor dat alles werkt in de editor en zorg ervoor dat het werkt op elk ander platform. Blijf werken in de editor. Het is eenvoudig om een nieuw platform toe te voegen aan Play-In-Editor. Het is erg moeilijk om Play-In-Editor aan de slag te krijgen als uw app alleen op een apparaat werkt.

Nieuwe openbare velden, eigenschappen, methoden en geserialiseerde privévelden met zorg toevoegen

Telkens wanneer u een openbare methode, veld, eigenschap toevoegt, wordt deze onderdeel van het openbare API-oppervlak van MRTK. Privévelden die zijn gemarkeerd met [SerializeField] , geven velden ook weer aan de editor en maken deel uit van het openbare API-oppervlak. Anderen kunnen deze openbare methode gebruiken, aangepaste prefabs configureren met uw openbare veld en er een afhankelijkheid van nemen.

Nieuwe publieke leden moeten zorgvuldig worden onderzocht. Alle openbare velden moeten in de toekomst worden onderhouden. Houd er rekening mee dat als het type van een openbaar veld (of geserialiseerd privéveld) verandert of wordt verwijderd uit een MonoBehaviour, dit andere personen kan breken. Het veld moet eerst worden afgeschaft voor een release en er moet code worden opgegeven voor het migreren van wijzigingen voor personen die afhankelijkheden hebben genomen.

Schrijftests prioriteren

MRTK is een communityproject, gewijzigd door een breed scala aan inzenders. Deze inzenders kennen mogelijk de details van uw foutoplossing/functie niet en breken per ongeluk uw functie. MRTK voert continue integratietests uit voordat elke pull-aanvraag wordt voltooid. Wijzigingen die tests onderbreken, kunnen niet worden ingecheckt. Daarom zijn tests de beste manier om ervoor te zorgen dat andere personen uw functie niet onderbreken.

Wanneer u een fout oplost, schrijft u een test om ervoor te zorgen dat deze in de toekomst niet achteruit gaat. Als u een functie toevoegt, schrijft u tests die controleren of uw functie werkt. Dit is vereist voor alle UX-functies, met uitzondering van experimentele functies.

C#-coderingsconventies

Headers van scriptlicentiegegevens

Alle Microsoft-werknemers die nieuwe bestanden bijdragen, moeten de volgende standaardlicentieheader toevoegen aan de bovenkant van nieuwe bestanden, precies zoals hieronder wordt weergegeven:

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

Samenvattingsheaders van functies/methoden

Alle openbare klassen, structs, opsommingen, functies, eigenschappen, velden die naar MRTK zijn gepost, moeten worden beschreven naar het doel en gebruik ervan, precies zoals hieronder wordt weergegeven:

/// <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;
}

Dit zorgt ervoor dat documentatie correct wordt gegenereerd en verspreid voor alle klassen, methoden en eigenschappen.

Scriptbestanden die zonder de juiste overzichtstags zijn verzonden, worden geweigerd.

MRTK-naamruimteregels

De Mixed Reality Toolkit maakt gebruik van een op functies gebaseerd naamruimtemodel, waarbij alle basisnaamruimten beginnen met 'Microsoft.MixedReality.Toolkit'. Over het algemeen hoeft u de toolkit-laag (bijvoorbeeld: Core, Providers, Services) niet op te geven in uw naamruimten.

De momenteel gedefinieerde naamruimten zijn:

  • 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

Voor naamruimten met een grote hoeveelheid typen is het acceptabel om een beperkt aantal subnaamruimten te maken om het bereik van het gebruik te bepalen.

Als u de naamruimte voor een interface, klasse of gegevenstype weglaat, wordt uw wijziging geblokkeerd.

Nieuwe MonoBehaviour-scripts toevoegen

Wanneer u nieuwe MonoBehaviour-scripts toevoegt met een pull-aanvraag, moet u ervoor zorgen dat het AddComponentMenu kenmerk wordt toegepast op alle toepasselijke bestanden. Dit zorgt ervoor dat het onderdeel eenvoudig kan worden gevonden in de editor onder de knop Onderdeel toevoegen . De kenmerkvlag is niet nodig als het onderdeel niet kan worden weergegeven in de editor, zoals een abstracte klasse.

In het onderstaande voorbeeld moet het pakket hier worden gevuld met de pakketlocatie van het onderdeel. Als u een item in de MAP MRTK/SDK plaatst, wordt het pakket SDK.

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

Nieuwe Unity Inspector-scripts toevoegen

Over het algemeen kunt u voorkomen dat er aangepaste controlescripts voor MRTK-onderdelen worden gemaakt. Het voegt extra overhead en beheer toe van de codebasis die kan worden verwerkt door de Unity-engine.

Als een inspectorklasse nodig is, probeert u de unity-klasse DrawDefaultInspector()te gebruiken. Dit vereenvoudigt opnieuw de inspector-klasse en laat veel van het werk over aan Unity.

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

Als aangepaste rendering is vereist in de inspector-klasse, probeert u en EditorGUILayout.PropertyFieldte gebruikenSerializedProperty. Dit zorgt ervoor dat Unity de weergave van geneste prefabs en gewijzigde waarden correct verwerkt.

Als EditorGUILayout.PropertyField niet kan worden gebruikt vanwege een vereiste in aangepaste logica, zorgt u ervoor dat al het gebruik wordt verpakt rond een EditorGUI.PropertyScope. Dit zorgt ervoor dat Unity de inspector correct weergeeft voor geneste prefabs en gewijzigde waarden met de opgegeven eigenschap.

Probeer bovendien de aangepaste inspector-klasse te versieren met een CanEditMultipleObjects. Deze tag zorgt ervoor dat meerdere objecten met dit onderdeel in de scène kunnen worden geselecteerd en gewijzigd. Nieuwe controleklassen moeten testen of de code werkt in deze situatie in de scène.

    // 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;
                    });
            }
        }
    }

Nieuwe ScriptableObjects toevoegen

Wanneer u nieuwe ScriptableObject-scripts toevoegt, moet u ervoor zorgen dat het CreateAssetMenu kenmerk wordt toegepast op alle toepasselijke bestanden. Dit zorgt ervoor dat het onderdeel eenvoudig te vinden is in de editor via de menu's voor het maken van assets. De kenmerkvlag is niet nodig als het onderdeel niet kan worden weergegeven in de editor, zoals een abstracte klasse.

In het onderstaande voorbeeld moet de submap worden gevuld met de MRTK-submap, indien van toepassing. Als u een item in de map MRTK/Providers plaatst, is het pakket Providers. Als u een item in de map MRTK/Core plaatst, stelt u dit in op Profielen.

In het onderstaande voorbeeld is de MyNewService | MyNewProvider moet worden gevuld met de naam van uw nieuwe klasse, indien van toepassing. Als u een item in de map MixedRealityToolkit plaatst, laat u deze tekenreeks weg.

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

Logboekregistratie

Wanneer u nieuwe functies toevoegt of bestaande functies bijwerkt, kunt u DebugUtilities.LogVerbose-logboeken toevoegen aan interessante code die nuttig kan zijn voor toekomstige foutopsporing. Er is hier een compromis tussen het toevoegen van logboekregistratie en de toegevoegde ruis en onvoldoende logboekregistratie (waardoor de diagnose moeilijk wordt).

Een interessant voorbeeld waarbij logboekregistratie nuttig is (samen met een interessante nettolading):

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

Dit type logboekregistratie kan helpen bij het ondervangen van problemen zoals https://github.com/microsoft/MixedRealityToolkit-Unity/issues/8016, die worden veroorzaakt door niet-overeenkomende bron gedetecteerde en verloren brongebeurtenissen.

Vermijd het toevoegen van logboeken voor gegevens en gebeurtenissen die zich in elk frame voordoen. In het ideale geval moet logboekregistratie betrekking hebben op 'interessante' gebeurtenissen die worden aangestuurd door afzonderlijke gebruikersinvoer (d.w.z. een 'klik' door een gebruiker en de reeks wijzigingen en gebeurtenissen die afkomstig zijn van die interessant zijn om te registreren). De doorlopende status 'gebruiker houdt nog steeds een gebaar vast' geregistreerd elk frame is niet interessant en zal de logboeken overbelasten.

Houd er rekening mee dat deze uitgebreide logboekregistratie niet standaard is ingeschakeld (dit moet zijn ingeschakeld in de instellingen van het diagnostische systeem)

Spaties versus tabbladen

Zorg ervoor dat u 4 spaties gebruikt in plaats van tabbladen wanneer u een bijdrage levert aan dit project.

Afstand

Voeg geen extra spaties toe tussen vierkante haken en haakjes:

Niet doen

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

Wel doen

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

Naamconventies

Altijd gebruiken PascalCase voor eigenschappen. Gebruik camelCase voor de meeste velden, met uitzondering van voor PascalCasestatic readonly velden en const . De enige uitzondering hierop is voor gegevensstructuren waarvoor de velden moeten worden geserialiseerd door de JsonUtility.

Niet doen

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

Wel doen

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

Wijzigingsfuncties voor toegang

Declareer altijd een wijzigingsfunctie voor toegang voor alle velden, eigenschappen en methoden.

  • Alle Unity API-methoden moeten standaard zijn private , tenzij u ze in een afgeleide klasse moet overschrijven. In dit geval protected moet worden gebruikt.

  • Velden moeten altijd , met public of protected eigenschapstoegangsors zijnprivate.

  • Waar mogelijk leden met een expressie en automatische eigenschappen gebruiken

Niet doen

// 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() { }

Wel doen

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

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

Accolades gebruiken

Gebruik altijd accolades na elk instructieblok en plaats deze op de volgende regel.

Niet doen

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

Niet doen

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

Wel doen

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

Openbare klassen, structs en opsommingen moeten allemaal in hun eigen bestanden worden opgenomen

Als de klasse, struct of opsomming privé kan worden gemaakt, is het prima om in hetzelfde bestand te worden opgenomen. Dit voorkomt compilatieproblemen met Unity en zorgt ervoor dat de juiste codeabstractie plaatsvindt. Het vermindert ook conflicten en wijzigingen die fouten veroorzaken wanneer code moet worden gewijzigd.

Niet doen

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

Wel doen

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

Wel doen

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;
}

Opsommingen initialiseren

Om ervoor te zorgen dat alle opsommingen correct worden geïnitialiseerd vanaf 0, biedt .NET u een overzichtelijke snelkoppeling om de enum automatisch te initialiseren door alleen de eerste (starters)waarde toe te voegen. (Waarde 1 = 0 De resterende waarden zijn bijvoorbeeld niet vereist)

Niet doen

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

Wel doen

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

Volgorde-opsommingen voor de juiste extensie

Het is van cruciaal belang dat als een Enum in de toekomst waarschijnlijk zal worden uitgebreid, om standaardwaarden bovenaan de Enum te ordenen, dit ervoor zorgt dat Enum-indexen niet worden beïnvloed met nieuwe toevoegingen.

Niet doen

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

Wel doen

/// <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
}

Opsommingsgebruik voor bitfields controleren

Als er een mogelijkheid is voor een opsomming om meerdere statussen als waarde te vereisen, bijvoorbeeld Handedness = Left & Right. Vervolgens moet de Enum correct worden ingericht met BitFlags om het correct te kunnen gebruiken

Het bestand Handedness.cs heeft hiervoor een concrete implementatie

Niet doen

public enum Handedness
{
    None,
    Left,
    Right
}

Wel doen

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

In code vastgelegde bestandspaden

Ga als volgt te werk bij het genereren van paden voor tekenreeksbestanden en met name bij het schrijven van in code vastgelegde tekenreekspaden:

  1. Gebruik waar mogelijk de API's vanPath C#, zoals Path.Combine of Path.GetFullPath.
  2. Gebruik / of Path.DirectorySeparatorChar in plaats van \ of \\.

Deze stappen zorgen ervoor dat MRTK werkt op zowel Windows- als Unix-systemen.

Niet doen

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

string filePath = myVarRootPath + myRelativePath;

Wel doen

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);

Best practices, inclusief Unity-aanbevelingen

Sommige van de doelplatforms van dit project moeten rekening houden met de prestaties. Wees daarom altijd voorzichtig met het toewijzen van geheugen in vaak aangeroepen code in strakke updatelussen of algoritmen.

Inkapseling

Gebruik altijd privévelden en openbare eigenschappen als toegang tot het veld van buiten de klasse of struct nodig is. Zorg ervoor dat u het privéveld en de openbare eigenschap samen vindt. Hierdoor is het gemakkelijker om in één oogopslag te zien wat de back-up van de eigenschap is en dat het veld script kan worden gewijzigd.

Notitie

De enige uitzondering hierop is voor gegevensstructuren waarvoor de velden moeten worden geserialiseerd door de JsonUtility, waarbij een gegevensklasse is vereist om alle openbare velden te hebben om de serialisatie te laten werken.

Niet doen

private float myValue1;
private float myValue2;

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

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

Wel doen

// 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
    }
}

Cachewaarden en serialiseer ze waar mogelijk in de scène/prefab

Met de HoloLens in het achterhoofd, is het het beste om te optimaliseren voor prestaties en cacheverwijzingen in de scène of prefab om runtimegeheugentoewijzingen te beperken.

Niet doen

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

Wel doen

[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);
}

Cacheverwijzingen naar materialen, roep de '.material' niet elke keer aan

Unity maakt een nieuw materiaal telkens wanneer u .material gebruikt, wat een geheugenlek veroorzaakt als het niet goed wordt opgeschoond.

Niet doen

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

Wel doen

// 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);
    }
}

Notitie

U kunt ook de eigenschap SharedMaterial van Unity gebruiken, waarmee niet telkens een nieuw materiaal wordt gemaakt wanneer er naar wordt verwezen.

Platformafhankelijke compilatie gebruiken om ervoor te zorgen dat de toolkit de build op een ander platform niet onderbreekt

  • Gebruik WINDOWS_UWP om UWP-specifieke, niet-Unity-API's te gebruiken. Dit voorkomt dat ze proberen uit te voeren in de editor of op niet-ondersteunde platforms. Dit is gelijk aan UNITY_WSA && !UNITY_EDITOR en moet worden gebruikt in het voordeel van.
  • Gebruik UNITY_WSA om UWP-specifieke Unity-API's te gebruiken, zoals de UnityEngine.XR.WSA naamruimte. Dit wordt uitgevoerd in de editor wanneer het platform is ingesteld op UWP, evenals in ingebouwde UWP-apps.

Aan de hand van deze grafiek kunt u bepalen wat #if u wilt gebruiken, afhankelijk van uw gebruiksscenario's en de build-instellingen die u verwacht.

Platform UWP IL2CPP UWP .NET Editor
UNITY_EDITOR False False Waar
UNITY_WSA Waar Waar Waar
WINDOWS_UWP Waar Waar False
UNITY_WSA && !UNITY_EDITOR Waar Waar False
ENABLE_WINMD_SUPPORT Waar Waar False
NETFX_CORE False Waar Niet waar

Geef de voorkeur aan DateTime.UtcNow boven DateTime.Now

DateTime.UtcNow is sneller dan DateTime.Now. In eerdere prestatieonderzoeken hebben we vastgesteld dat het gebruik van DateTime.Now een aanzienlijke overhead toevoegt, met name wanneer deze wordt gebruikt in de lus Update(). Anderen hebben hetzelfde probleem.

Gebruik liever DateTime.UtcNow, tenzij u de gelokaliseerde tijden daadwerkelijk nodig hebt (een legitieme reden kan zijn dat u de huidige tijd in de tijdzone van de gebruiker wilt weergeven). Als u te maken hebt met relatieve tijden (d.w.z. de delta tussen een laatste update en nu), kunt u het beste DateTime.UtcNow gebruiken om de overhead van het uitvoeren van tijdzoneconversies te voorkomen.

PowerShell-coderingsconventies

Een subset van de MRTK-codebasis maakt gebruik van PowerShell voor pijplijninfrastructuur en verschillende scripts en hulpprogramma's. Nieuwe PowerShell-code moet de stijl PoshCode volgen.

Zie ook

C#-coderingsconventies van MSDN