Předdefinované referenční typy (Referenční dokumentace jazyka C#)
Jazyk C# má mnoho vestavěných typů odkazů. Mají klíčová slova nebo operátory, které jsou synonyma pro typ v knihovně .NET.
Typ objektu
objectTyp je alias System.Object v rozhraní .NET. V rámci sjednoceného typu systému C# všechny typy, předdefinované a uživatelsky definované typy odkazů a typy hodnot dědí přímo nebo nepřímo z System.Object . K proměnným typu můžete přiřadit hodnoty libovolného typu object . Jakoukoli object proměnnou lze přiřadit její výchozí hodnotě pomocí literálu null . Když je proměnná typu hodnoty převedena na typ Object, je označována jako zabalená. Je-li proměnná typu object převedena na typ hodnoty, je označována jako nezabaleno. Další informace naleznete v tématu zabalení a rozbalení.
Typ řetězce
stringTyp představuje sekvenci nula nebo více znaků Unicode. string je alias pro System.String v rozhraní .NET.
I když string je odkazový typ, operátory rovnosti == != a jsou definovány pro porovnání hodnot string objektů, nikoli odkazů. Díky tomu je testování rovnosti řetězců intuitivnější. Například:
string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine(object.ReferenceEquals(a, b));
Zobrazí se hodnota "true" a potom "false", protože obsah řetězců je ekvivalentní, ale a b neodkazuje na stejnou instanci řetězce.
Operátor + zřetězí řetězce:
string a = "good " + "morning";
Tím se vytvoří objekt String, který obsahuje "Dobré ráno".
Řetězce jsou neměnné– obsah objektu String nelze po vytvoření objektu změnit, i když se syntaxe zobrazí jako v případě, že to můžete provést. Například při psaní tohoto kódu kompilátor ve skutečnosti vytvoří nový objekt řetězce, který bude obsahovat novou posloupnost znaků a který je přiřazen k novému objektu b . Paměť, která byla přidělena pro b (pokud obsahuje řetězec "h"), je pak vhodná pro uvolňování paměti.
string b = "h";
b += "ello";
[] Operátor lze použít pro přístup jen pro čtení k jednotlivým znakům řetězce. Platné hodnoty indexu začínají na 0 a musí být menší než délka řetězce:
string str = "test";
char x = str[2]; // x = 's';
Podobným způsobem [] lze operátor také použít pro iteraci každého znaku v řetězci:
string str = "test";
for (int i = 0; i < str.Length; i++)
{
Console.Write(str[i] + " ");
}
// Output: t e s t
Řetězcové literály jsou typu string a mohou být zapsány ve dvou formulářích, v uvozovkách a v @ uvozovkách. Řetězcové literály v uvozovkách jsou uzavřeny v uvozovkách ("):
"good morning" // a string literal
Řetězcové literály můžou obsahovat libovolný znakový literál. K dispozici jsou řídicí sekvence. Následující příklad používá řídicí sekvenci \\ zpětného lomítka, \u0066 pro písmeno f a \n pro nový řádek.
string a = "\\\u0066\n F";
Console.WriteLine(a);
// Output:
// \f
// F
Poznámka
Řídicí kód \udddd (kde dddd je číslo se čtyřmi číslicemi) představuje znak Unicode U + dddd . Rozpoznávají se také osmimístného kódů Escape Unicode: \Udddddddd .
Doslovné řetězce literálů začínají @ na a jsou také uzavřeny v uvozovkách. Například:
@"good morning" // a string literal
výhodou doslovného řetězce je, že řídicí sekvence nejsou zpracovávány , což usnadňuje zápis, například plně kvalifikovaný Windows název souboru:
@"c:\Docs\Source\a.txt" // rather than "c:\\Docs\\Source\\a.txt"
Chcete-li do řetězce zahrnout dvojitou uvozovku @-quoted , Zdvojnásobte si ho:
@"""Ahoy!"" cried the captain." // "Ahoy!" cried the captain.
Typ delegáta
Deklarace typu delegáta je podobná podpisu metody. Má návratovou hodnotu a libovolný počet parametrů libovolného typu:
public delegate void MessageDelegate(string message);
public delegate int AnotherDelegate(MyType m, long num);
V rozhraní .NET System.Action a System.Func typy poskytují obecné definice pro mnoho běžných delegátů. Pravděpodobně nebudete muset definovat nové vlastní typy delegátů. Místo toho můžete vytvořit instance poskytnutých obecných typů.
delegateJe odkazový typ, který lze použít k zapouzdření pojmenované nebo anonymní metody. Delegáti jsou podobní ukazatelům funkcí v jazyce C++; Delegáti jsou však typově bezpečné a zabezpečené. Pro aplikace delegátů, přečtěte si téma Delegáti a Obecné delegáty. Delegáti jsou základem pro události. Pro delegáta se dá vytvořit instance, a to tak, že ho přidružíte k pojmenované nebo anonymní metodě.
Pro delegáta musí být vytvořená metoda nebo lambda výraz, který má kompatibilní návratový typ a vstupní parametry. Další informace o stupni odchylky, která je povolena v signatuře metody, naleznete v tématu Variance in Delegates. Pro použití s anonymními metodami, delegát a kód, který je k němu přidružen, jsou deklarovány společně.
Kombinace a odebrání delegáta se nezdařila s výjimkou modulu runtime, pokud se typy delegátů, které jsou v době běhu, liší v důsledku převodu variant. Následující příklad ukazuje situaci, která se nezdařila:
Action<string> stringAction = str => {};
Action<object> objectAction = obj => {};
// Valid due to implicit reference conversion of
// objectAction to Action<string>, but may fail
// at run time.
Action<string> combination = stringAction + objectAction;
Můžete vytvořit delegáta se správným typem modulu runtime vytvořením nového objektu delegáta. Následující příklad ukazuje, jak lze toto alternativní řešení použít pro předchozí příklad.
Action<string> stringAction = str => {};
Action<object> objectAction = obj => {};
// Creates a new delegate instance with a runtime type of Action<string>.
Action<string> wrappedObjectAction = new Action<string>(objectAction);
// The two Action<string> delegate instances can now be combined.
Action<string> combination = stringAction + wrappedObjectAction;
Počínaje jazykem C# 9 můžete deklarovat ukazatele funkcí, které používají podobnou syntaxi. Ukazatel na funkci používá calli instrukci namísto vytvoření instance typu delegáta a volání virtuální Invoke metody.
Dynamický typ
dynamicTyp označuje, že použití proměnné a odkazů na její členy vynechává kontrolu typu při kompilaci. Místo toho se tyto operace vyřeší za běhu. dynamictyp zjednodušuje přístup k rozhraním api modelu COM, jako jsou Office rozhraní api pro automatizaci, do dynamických rozhraní api, jako jsou například knihovny ironpythonu, a HTML model DOM (Document Object Model) (DOM).
Typ dynamic object se ve většině případů chová jako typ. Konkrétně libovolný výraz, který není null, lze převést na dynamic typ. dynamicTyp se liší od object v tom, že operace obsahující výrazy typu dynamic nejsou vyřešeny nebo typ zkontrolovaný kompilátorem. Kompilátor balí informace o operaci a tyto informace jsou později použity k vyhodnocení operace v době běhu. V rámci procesu jsou proměnné typu dynamic kompilovány do proměnných typu object . Proto typ dynamic existuje pouze v době kompilace, nikoli v době běhu.
Následující příklad kontrastuje proměnnou typu dynamic na proměnnou typu object . Chcete-li ověřit typ každé proměnné v době kompilace, umístěte ukazatel myši nad dyn nebo obj v WriteLine příkazech. Zkopírujte následující kód do editoru, kde je k dispozici technologie IntelliSense. IntelliSense zobrazuje dynamický pro dyn objekt a pro obj .
class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;
// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
WriteLinePříkazy zobrazují běhové typy dyn a obj . V tomto okamžiku oba mají stejný typ Integer. Vytvoří se následující výstup:
System.Int32
System.Int32
Chcete-li zobrazit rozdíl mezi dyn a obj v době kompilace, přidejte následující dva řádky mezi deklaracemi a WriteLine příkazy v předchozím příkladu.
dyn = dyn + 3;
obj = obj + 3;
Chyba kompilátoru je hlášena při pokusu o přidání celého čísla a objektu ve výrazu obj + 3 . Není však hlášena žádná chyba pro dyn + 3 . Výraz, který obsahuje, dyn není kontrolován v době kompilace, protože typ dyn je dynamic .
Následující příklad používá dynamic v několika deklaracích. MainMetoda také kontrastuje při kontrole typu za běhu při kontrole typu za běhu.
using System;
namespace DynamicExamples
{
class Program
{
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass();
Console.WriteLine(ec.exampleMethod(10));
Console.WriteLine(ec.exampleMethod("value"));
// The following line causes a compiler error because exampleMethod
// takes only one argument.
//Console.WriteLine(ec.exampleMethod(10, 4));
dynamic dynamic_ec = new ExampleClass();
Console.WriteLine(dynamic_ec.exampleMethod(10));
// Because dynamic_ec is dynamic, the following call to exampleMethod
// with two arguments does not produce an error at compile time.
// However, it does cause a run-time error.
//Console.WriteLine(dynamic_ec.exampleMethod(10, 4));
}
}
class ExampleClass
{
static dynamic field;
dynamic prop { get; set; }
public dynamic exampleMethod(dynamic d)
{
dynamic local = "Local variable";
int two = 2;
if (d is int)
{
return local;
}
else
{
return two;
}
}
}
}
// Results:
// Local variable
// 2
// Local variable
Viz také
- Reference jazyka C#
- Klíčová slova jazyka C#
- Události
- Použití typu dynamic
- Osvědčené postupy pro používání řetězců
- Základní operace s řetězci
- Vytváření nových řetězců
- Operátory pro testování typů a přetypování
- Jak bezpečně přetypovat pomocí porovnávání vzorů a operátorů as a is
- Návod: vytváření a používání dynamických objektů
- System.Object
- System.String
- System.Dynamic.DynamicObject