Wbudowane typy odwołań (C# odwołanie)Built-in reference types (C# reference)

C#ma wiele wbudowanych typów odwołań.C# has a number of built-in reference types. Mają słowa kluczowe lub operatory, które są synonimami dla typu w bibliotece .NET.They have keywords or operators that are synonyms for a type in the .NET library.

Typ obiektuThe object type

Typ object jest aliasem dla System.Object w programie .NET.The object type is an alias for System.Object in .NET. W ujednoliconym systemie typów systemu C#, wszystkie typy, wstępnie zdefiniowane i zdefiniowane przez użytkownika, typy odwołań i typy wartości, dziedziczą bezpośrednio lub pośrednio z System.Object.In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from System.Object. Wartości dowolnego typu można przypisać do zmiennych typu object.You can assign values of any type to variables of type object. Dowolna zmienna object może być przypisana do jej wartości domyślnej przy użyciu nullliterału.Any object variable can be assigned to its default value using the literal null. Gdy zmienna typu wartości jest konwertowana na obiekt, jest określana jako opakowana.When a variable of a value type is converted to object, it is said to be boxed. Gdy zmienna typu Object jest konwertowana na typ wartości, jest ona określana jako nieopakowana.When a variable of type object is converted to a value type, it is said to be unboxed. Aby uzyskać więcej informacji, zobacz opakowanie i rozpakowywanie.For more information, see Boxing and Unboxing.

Typ ciąguThe string type

Typ string reprezentuje sekwencję zero lub więcej znaków Unicode.The string type represents a sequence of zero or more Unicode characters. string jest alias System.String na platformie .NET.string is an alias for System.String in .NET.

Chociaż string jest typem referencyjnym, Operatory równości == i != są zdefiniowane w celu porównania wartości obiektów string, a nie odwołań.Although string is a reference type, the equality operators == and != are defined to compare the values of string objects, not references. Dzięki temu testowanie w celu zapewnienia bardziej intuicyjnego testowania.This makes testing for string equality more intuitive. Na przykład:For example:

string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine(object.ReferenceEquals(a, b));

Spowoduje to wyświetlenie wartości "true", a następnie wartości "false", ponieważ zawartość ciągów jest równoważna, ale a i b nie odwołują się do tego samego wystąpienia ciągu.This displays "True" and then "False" because the content of the strings are equivalent, but a and b do not refer to the same string instance.

Operator + łączy ciągi:The + operator concatenates strings:

string a = "good " + "morning";

Spowoduje to utworzenie obiektu ciągu zawierającego "dobry rano".This creates a string object that contains "good morning".

Ciągi są niezmienne— zawartość obiektu String nie może zostać zmieniona po utworzeniu obiektu, mimo że składnia wygląda tak, jakby to możliwe.Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this. Na przykład podczas pisania tego kodu kompilator tworzy nowy obiekt String, aby pomieścić nową sekwencję znaków i nowy obiekt został przypisany do b.For example, when you write this code, the compiler actually creates a new string object to hold the new sequence of characters, and that new object is assigned to b. Pamięć, która została przypisana do b (gdy zawiera ciąg "h"), kwalifikuje się do wyrzucania elementów bezużytecznych.The memory that had been allocated for b (when it contained the string "h") is then eligible for garbage collection.

string b = "h";
b += "ello";

Operatora [] można używać do dostępu tylko do odczytu do poszczególnych znaków string.The [] operator can be used for readonly access to individual characters of a string. Prawidłowe wartości zaczynają się o 0 i muszą być mniejsze niż długość string:Valid values start at 0 and must be less than the length of the string:

string str = "test";
char x = str[2];  // x = 's';

W podobny sposób operator [] może być również używany do iteracji dla każdego znaku w string:In similar fashion, the [] operator can also be used for iterating over each character in a string:

string str = "test";

for (int i = 0; i < str.Length; i++)
{
  Console.Write(str[i] + " ");
}
// Output: t e s t

Literały ciągu są typu string i mogą być zapisywane w dwóch postaciach, cytowane i @.String literals are of type string and can be written in two forms, quoted and @-quoted. Cudzysłowy ujęte w cudzysłów są ujęte w znaki podwójnego cudzysłowu ("):Quoted string literals are enclosed in double quotation marks ("):

"good morning"  // a string literal

Literały ciągu mogą zawierać dowolny literał znakowy.String literals can contain any character literal. Sekwencje ucieczki są uwzględniane.Escape sequences are included. W poniższym przykładzie zastosowano sekwencję ucieczki \\ dla ukośnika odwrotnego, \u0066 dla litery f i \n dla nowego wiersza.The following example uses escape sequence \\ for backslash, \u0066 for the letter f, and \n for newline.

string a = "\\\u0066\n F";
Console.WriteLine(a);
\\ Output:
\\ \f
\\  F

Uwaga

Kod ucieczki \udddd (gdzie dddd jest liczbą czterocyfrową) reprezentuje znak Unicode U +dddd.The escape code \udddd (where dddd is a four-digit number) represents the Unicode character U+dddd. Są również rozpoznawane osiem cyfrowych kodów ucieczki Unicode: \Udddddddd.Eight-digit Unicode escape codes are also recognized: \Udddddddd.

Literały ciągu Verbatim rozpoczynają się od @ i są również ujęte w znaki podwójnego cudzysłowu.Verbatim string literals start with @ and are also enclosed in double quotation marks. Na przykład:For example:

@"good morning"  // a string literal

Zaletą ciągów Verbatim jest to, że sekwencje unikowe nie są przetwarzane, co ułatwia pisanie, na przykład w pełni kwalifikowanej nazwy pliku systemu Windows:The advantage of verbatim strings is that escape sequences are not processed, which makes it easy to write, for example, a fully qualified Windows file name:

@"c:\Docs\Source\a.txt"  // rather than "c:\\Docs\\Source\\a.txt"

Aby uwzględnić podwójny cudzysłów w ciągu @-quoted, należy go dwukrotnie:To include a double quotation mark in an @-quoted string, double it:

@"""Ahoy!"" cried the captain." // "Ahoy!" cried the captain.

Typ delegataThe delegate type

Deklaracja typu delegata jest podobna do sygnatury metody.The declaration of a delegate type is similar to a method signature. Ma ona wartość zwracaną i dowolną liczbę parametrów dowolnego typu:It has a return value and any number of parameters of any type:

public delegate void MessageDelegate(string message);
public delegate int AnotherDelegate(MyType m, long num);

W programie .NET typy System.Action i System.Func zapewniają definicje ogólne dla wielu typowych delegatów.In .NET, System.Action and System.Func types provide generic definitions for many common delegates. Być może nie trzeba definiować nowych typów delegatów niestandardowych.You likely don't need to define new custom delegate types. Zamiast tego można tworzyć wystąpienia podanych typów ogólnych.Instead, you can create instantiations of the provided generic types.

delegate jest typem referencyjnym, którego można użyć do hermetyzacji metody nazwanej lub anonimowej.A delegate is a reference type that can be used to encapsulate a named or an anonymous method. Delegaty są podobne do wskaźników funkcji C++w; Delegaty są jednak bezpieczne i bezpieczne dla typów.Delegates are similar to function pointers in C++; however, delegates are type-safe and secure. W przypadku aplikacji delegatów zobacz Delegaty i delegatów ogólnych.For applications of delegates, see Delegates and Generic Delegates. Delegaty są podstawą dla zdarzeń.Delegates are the basis for Events. Można utworzyć wystąpienie delegata, kojarząc go z metodami nazwanymi lub anonimowymi.A delegate can be instantiated by associating it either with a named or anonymous method.

Obiekt delegowany musi być skonkretyzowany przy użyciu metody lub wyrażenia lambda, które ma zgodny typ zwracany i parametry wejściowe.The delegate must be instantiated with a method or lambda expression that has a compatible return type and input parameters. Aby uzyskać więcej informacji na temat stopnia wariancji, który jest dozwolony w sygnaturze metody, zobacz Wariancja w delegatach.For more information on the degree of variance that is allowed in the method signature, see Variance in Delegates. Aby można było korzystać z metod anonimowych, delegat i kod, który ma być skojarzony z nim, są deklarowane razem.For use with anonymous methods, the delegate and the code to be associated with it are declared together.

Typ dynamicznyThe dynamic type

Typ dynamic wskazuje, że użycie zmiennej i odwołań do jej elementów członkowskich obejście sprawdzania typu w czasie kompilacji.The dynamic type indicates that use of the variable and references to its members bypass compile-time type checking. Zamiast tego te operacje są rozwiązywane w czasie wykonywania.Instead, these operations are resolved at run time. Typ dynamic upraszcza dostęp do interfejsów API modelu COM, takich jak interfejsy API usługi Office Automation, do dynamicznych interfejsów API, takich jak biblioteki IronPython, oraz do Document Object Model HTML (DOM).The dynamic type simplifies access to COM APIs such as the Office Automation APIs, to dynamic APIs such as IronPython libraries, and to the HTML Document Object Model (DOM).

Typ dynamic zachowuje się jak typ object w większości sytuacji.Type dynamic behaves like type object in most circumstances. W szczególności każde wyrażenie o wartości innej niż null można przekonwertować na typ dynamic.In particular, any non-null expression can be converted to the dynamic type. Typ dynamic różni się od object w tym, że operacje, które zawierają wyrażenia typu dynamic nie są rozpoznawane lub typem sprawdzonym przez kompilator.The dynamic type differs from object in that operations that contain expressions of type dynamic are not resolved or type checked by the compiler. Kompilator pakuje razem informacje o operacji, a informacje te są później używane do szacowania operacji w czasie wykonywania.The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. W ramach procesu zmienne typu dynamic są kompilowane do zmiennych typu object.As part of the process, variables of type dynamic are compiled into variables of type object. W związku z tym, typ dynamic istnieje tylko w czasie kompilacji, a nie w czasie wykonywania.Therefore, type dynamic exists only at compile time, not at run time.

Poniższy przykład kontrastuje zmienną typu dynamic do zmiennej typu object.The following example contrasts a variable of type dynamic to a variable of type object. Aby sprawdzić typ każdej zmiennej w czasie kompilacji, umieść wskaźnik myszy nad dyn lub obj w instrukcji WriteLine.To verify the type of each variable at compile time, place the mouse pointer over dyn or obj in the WriteLine statements. Skopiuj poniższy kod do edytora, w którym jest dostępna funkcja IntelliSense.Copy the following code into an editor where IntelliSense is available. Funkcja IntelliSense wyświetla dynamiczny dla dyn i obiektu dla obj.IntelliSense shows dynamic for dyn and object for 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());
    }
}

Instrukcje WriteLine wyświetlają typy czasu wykonywania dyn i obj.The WriteLine statements display the run-time types of dyn and obj. W tym momencie oba mają ten sam typ, liczba całkowita.At that point, both have the same type, integer. Generowane są następujące dane wyjściowe:The following output is produced:

System.Int32
System.Int32

Aby zobaczyć różnicę między dyn i obj w czasie kompilacji, Dodaj następujące dwa wiersze między deklaracjami i instrukcjami WriteLine w poprzednim przykładzie.To see the difference between dyn and obj at compile time, add the following two lines between the declarations and the WriteLine statements in the previous example.

dyn = dyn + 3;
obj = obj + 3;

Zgłoszono błąd kompilatora dla próby dodania liczby całkowitej i obiektu w wyrażeniu obj + 3.A compiler error is reported for the attempted addition of an integer and an object in expression obj + 3. Nie jest jednak zgłaszany żaden błąd dla dyn + 3.However, no error is reported for dyn + 3. Wyrażenie zawierające dyn nie jest sprawdzane w czasie kompilacji, ponieważ typ dyn jest dynamic.The expression that contains dyn is not checked at compile time because the type of dyn is dynamic.

Poniższy przykład używa dynamic w kilku deklaracjach.The following example uses dynamic in several declarations. Metoda Main również kontrastuje sprawdzanie typu w czasie kompilacji przy użyciu sprawdzania typu w czasie wykonywania.The Main method also contrasts compile-time type checking with run-time type checking.

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

Zobacz takżeSee also