This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Built-in reference types (C# reference)
- 9 contributors
C# has many built-in reference types. They have keywords or operators that are synonyms for a type in the .NET library.
The object type
The object type is an alias for System.Object in .NET. 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 . You can assign values of any type (except ref struct , see ref struct ) to variables of type object . Any object variable can be assigned to its default value using the literal null . When a variable of a value type is converted to object, it's said to be boxed . When a variable of type object is converted to a value type, it's said to be unboxed . For more information, see Boxing and Unboxing .
The string type
The string type represents a sequence of zero or more Unicode characters. string is an alias for System.String in .NET.
Although string is a reference type, the equality operators == and != are defined to compare the values of string objects, not references. Value based equality makes testing for string equality more intuitive. For example:
The previous example displays "True" and then "False" because the content of the strings is equivalent, but a and b don't refer to the same string instance.
The + operator concatenates strings:
The preceding code creates a string object that contains "good morning".
Strings are immutable --the contents of a string object can't be changed after the object is created. 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 . The memory that had been allocated for b (when it contained the string "h") is then eligible for garbage collection.
The [] operator can be used for readonly access to individual characters of a string. Valid index values start at 0 and must be less than the length of the string:
In similar fashion, the [] operator can also be used for iterating over each character in a string:
String literals
String literals are of type string and can be written in three forms, raw, quoted, and verbatim.
Raw string literals are available beginning in C# 11. Raw string literals can contain arbitrary text without requiring escape sequences. Raw string literals can include whitespace and new lines, embedded quotes, and other special characters. Raw string literals are enclosed in a minimum of three double quotation marks ("""):
You can even include a sequence of three (or more) double quote characters. If your text requires an embedded sequence of quotes, you start and end the raw string literal with more quote marks, as needed:
Raw string literals typically have the starting and ending quote sequences on separate lines from the embedded text. Multiline raw string literals support strings that are themselves quoted strings:
When the starting and ending quotes are on separate lines, the newlines following the opening quote and preceding the ending quote aren't included in the final content. The closing quote sequence dictates the leftmost column for the string literal. You can indent a raw string literal to match the overall code format:
Columns to the right of the ending quote sequence are preserved. This behavior enables raw strings for data formats such as JSON, YAML, or XML, as shown in the following example:
The compiler issues an error if any of the text lines extend to the left of the closing quote sequence. The opening and closing quote sequences can be on the same line, providing the string literal neither starts nor ends with a quote character:
You can combine raw string literals with string interpolation to include quote characters and braces in the output string.
Quoted string literals are enclosed in double quotation marks ("):
String literals can contain any character literal. Escape sequences are included. The following example uses escape sequence \\ for backslash, \u0066 for the letter f, and \n for newline.
The escape code \udddd (where dddd is a four-digit number) represents the Unicode character U+ dddd . Eight-digit Unicode escape codes are also recognized: \Udddddddd .
Verbatim string literals start with @ and are also enclosed in double quotation marks. For example:
The advantage of verbatim strings is that escape sequences aren't processed, which makes it easy to write. For example, the following text matches a fully qualified Windows file name:
To include a double quotation mark in an @-quoted string, double it:
UTF-8 string literals
Strings in .NET are stored using UTF-16 encoding. UTF-8 is the standard for Web protocols and other important libraries. Beginning in C# 11, you can add the u8 suffix to a string literal to specify UTF-8 encoding. UTF-8 literals are stored as ReadOnlySpan<byte> objects. The natural type of a UTF-8 string literal is ReadOnlySpan<byte> . Using a UTF-8 string literal creates a more clear declaration than declaring the equivalent System.ReadOnlySpan<T> , as shown in the following code:
To store a UTF-8 string literal as an array requires the use of ReadOnlySpan<T>.ToArray() to copy the bytes containing the literal to the mutable array:
UTF-8 string literals aren't compile time constants; they're runtime constants. Therefore, they can't be used as the default value for an optional parameter. UTF-8 string literals can't be combined with string interpolation. You can't use the $ token and the u8 suffix on the same string expression.
The delegate type
The declaration of a delegate type is similar to a method signature. It has a return value and any number of parameters of any type:
In .NET, System.Action and System.Func types provide generic definitions for many common delegates. You likely don't need to define new custom delegate types. Instead, you can create instantiations of the provided generic types.
A delegate is a reference type that can be used to encapsulate a named or an anonymous method. Delegates are similar to function pointers in C++; however, delegates are type-safe and secure. For applications of delegates, see Delegates and Generic Delegates . Delegates are the basis for Events . A delegate can be instantiated by associating it either with a named or anonymous method.
The delegate must be instantiated with a method or lambda expression that has a compatible return type and input parameters. For more information on the degree of variance that is allowed in the method signature, see Variance in Delegates . For use with anonymous methods, the delegate and the code to be associated with it are declared together.
Delegate combination or removal fails with a runtime exception when the delegate types involved at run time are different due to variant conversion. The following example demonstrates a situation that fails:
You can create a delegate with the correct runtime type by creating a new delegate object. The following example demonstrates how this workaround may be applied to the preceding example.
You can declare function pointers , which use similar syntax. A function pointer uses the calli instruction instead of instantiating a delegate type and calling the virtual Invoke method.
The dynamic type
The dynamic type indicates that use of the variable and references to its members bypass compile-time type checking. Instead, these operations are resolved at run time. 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).
Type dynamic behaves like type object in most circumstances. In particular, any non-null expression can be converted to the dynamic type. The dynamic type differs from object in that operations that contain expressions of type dynamic aren't resolved or type checked by the compiler. The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. As part of the process, variables of type dynamic are compiled into variables of type object . Therefore, type dynamic exists only at compile time, not at run time.
The following example contrasts a variable of type dynamic to a variable of type object . To verify the type of each variable at compile time, place the mouse pointer over dyn or obj in the WriteLine statements. Copy the following code into an editor where IntelliSense is available. IntelliSense shows dynamic for dyn and object for obj .
The WriteLine statements display the run-time types of dyn and obj . At that point, both have the same type, integer. The following output is produced:
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.
A compiler error is reported for the attempted addition of an integer and an object in expression obj + 3 . However, no error is reported for dyn + 3 . The expression that contains dyn isn't checked at compile time because the type of dyn is dynamic .
The following example uses dynamic in several declarations. The Main method also contrasts compile-time type checking with run-time type checking.
C# language specification
For more information, see the following sections of the C# language specification :
- §8.2.3 The object type
- §8.2.4 The dynamic type
- §8.2.5 The string type
- §8.2.8 Delegate types
- C# 11 - Raw string literals
- C# Keywords
- Using Type dynamic
- Best Practices for Using Strings
- Basic String Operations
- Creating New Strings
- Type-testing and cast operators
- How to safely cast using pattern matching and the as and is operators
- Walkthrough: creating and using dynamic objects
- System.Object
- System.String
- System.Dynamic.DynamicObject
Additional resources
Value Type and Reference Type
In C#, these data types are categorized based on how they store their value in the memory. C# includes the following categories of data types:
- Reference type
- Pointer type
A data type is a value type if it holds a data value within its own memory space. It means the variables of these data types directly contain values.
For example, consider integer variable int i = 100;
The system stores 100 in the memory space allocated for the variable i . The following image illustrates how 100 is stored at some hypothetical location in the memory (0x239110) for 'i':
The following data types are all of value type:
Passing Value Type Variables
When you pass a value-type variable from one method to another, the system creates a separate copy of a variable in another method. If value got changed in the one method, it wouldn't affect the variable in another method.
In the above example, variable i in the Main() method remains unchanged even after we pass it to the ChangeValue() method and change it's value there.
Reference Type
Unlike value types, a reference type doesn't store its value directly. Instead, it stores the address where the value is being stored. In other words, a reference type contains a pointer to another memory location that holds the data.
For example, consider the following string variable:
string s = "Hello World!!";
The following image shows how the system allocates the memory for the above string variable.
As you can see in the above image, the system selects a random location in memory (0x803200) for the variable s . The value of a variable s is 0x600000 , which is the memory address of the actual data value. Thus, reference type stores the address of the location where the actual value is stored instead of the value itself.
The followings are reference type data types:
- Arrays (even if their elements are value types)
Passing Reference Type Variables
When you pass a reference type variable from one method to another, it doesn't create a new copy; instead, it passes the variable's address. So, If we change the value of a variable in a method, it will also be reflected in the calling method.
In the above example, we pass the Student object std1 to the ChangeReferenceType() method. Here, it actually pass the memory address of std1 . Thus, when the ChangeReferenceType() method changes StudentName , it is actually changing StudentName of std1 object, because std1 and std2 are both pointing to the same address in memory.
String is a reference type, but it is immutable. It means once we assigned a value, it cannot be changed. If we change a string value, then the compiler creates a new string object in the memory and point a variable to the new memory location. So, passing a string value to a function will create a new variable in the memory, and any change in the value in the function will not be reflected in the original value, as shown below.
The default value of a reference type variable is null when they are not initialized. Null means not refering to any object.
A value type variable cannot be null because it holds value, not a memory address. C# 2.0 introduced nullable types , using which you can assign null to a value type variable or declare a value type variable without assigning a value to it.
- How to get the sizeof a datatype in C#?
- Difference between String and StringBuilder in C#
- Static vs Singleton in C#
- Difference between == and Equals() Method in C#
- Asynchronous programming with async, await, Task in C#
- How to loop through an enum in C#?
- Generate Random Numbers in C#
- Difference between Two Dates in C#
- Convert int to enum in C#
- BigInteger Data Type in C#
- Convert String to Enum in C#
- Convert an Object to JSON in C#
- Convert JSON String to Object in C#
- DateTime Formats in C#
- How to convert date object to string in C#?
- Compare strings in C#
- How to count elements in C# array?
- Difference between String and string in C#.
- How to get a comma separated string from an array in C#?
- Boxing and Unboxing in C#
- How to convert string to int in C#?
- More C# articles
We are a team of passionate developers, educators, and technology enthusiasts who, with their combined expertise and experience, create in -depth, comprehensive, and easy to understand tutorials.We focus on a blend of theoretical explanations and practical examples to encourages hands - on learning. Visit About Us page for more information.
- C# Questions & Answers
- C# Skill Test
- C# Latest Articles
- Free Tools for Students
- Harvard Referencing Generator
Free Harvard Referencing Generator
Generate accurate Harvard reference lists quickly and for FREE, with MyBib!
🤔 What is a Harvard Referencing Generator?
A Harvard Referencing Generator is a tool that automatically generates formatted academic references in the Harvard style.
It takes in relevant details about a source -- usually critical information like author names, article titles, publish dates, and URLs -- and adds the correct punctuation and formatting required by the Harvard referencing style.
The generated references can be copied into a reference list or bibliography, and then collectively appended to the end of an academic assignment. This is the standard way to give credit to sources used in the main body of an assignment.
👩🎓 Who uses a Harvard Referencing Generator?
Harvard is the main referencing style at colleges and universities in the United Kingdom and Australia. It is also very popular in other English-speaking countries such as South Africa, Hong Kong, and New Zealand. University-level students in these countries are most likely to use a Harvard generator to aid them with their undergraduate assignments (and often post-graduate too).
🙌 Why should I use a Harvard Referencing Generator?
A Harvard Referencing Generator solves two problems:
- It provides a way to organise and keep track of the sources referenced in the content of an academic paper.
- It ensures that references are formatted correctly -- inline with the Harvard referencing style -- and it does so considerably faster than writing them out manually.
A well-formatted and broad bibliography can account for up to 20% of the total grade for an undergraduate-level project, and using a generator tool can contribute significantly towards earning them.
⚙️ How do I use MyBib's Harvard Referencing Generator?
Here's how to use our reference generator:
- If citing a book, website, journal, or video: enter the URL or title into the search bar at the top of the page and press the search button.
- Choose the most relevant results from the list of search results.
- Our generator will automatically locate the source details and format them in the correct Harvard format. You can make further changes if required.
- Then either copy the formatted reference directly into your reference list by clicking the 'copy' button, or save it to your MyBib account for later.
MyBib supports the following for Harvard style:
🍏 What other versions of Harvard referencing exist?
There isn't "one true way" to do Harvard referencing, and many universities have their own slightly different guidelines for the style. Our generator can adapt to handle the following list of different Harvard styles:
- Cite Them Right
- Manchester Metropolitan University (MMU)
- University of the West of England (UWE)
Daniel is a qualified librarian, former teacher, and citation expert. He has been contributing to MyBib since 2018.
IMAGES
VIDEO