CSharp
lastmod 2025-05-30created 2015-05-0178 edits
C# is an object-oriented programming language developed by Microsoft. It was created as part of the .NET Framework and later became a standard of ECMA (ECMA-334) and ISO (ISO/IEC/23270). Its syntax is similar to C++ and Java.
C# is the programming language that most directly reflects the .NET platform on which .NET programs run, and it also depends heavily on that platform. Its syntactic characteristics are quite similar to Java, and many of the .NET platform technologies that C# works with were designed with Java in mind, so it is most often compared with Java. Unlike Java, however, C# puts considerable effort into cross-platform interoperability through technologies such as unsafe code. C#'s basic data types follow the .NET object model, memory is reclaimed at the runtime level (garbage collection), and it includes every element an object-oriented language should have, such as classes, interfaces, delegates, and exceptions.
Features
C# is the programming language that most directly reflects the .NET platform on which .NET programs run, and it also depends heavily on that platform. Its syntactic characteristics are quite similar to Java, and many of the .NET platform technologies that C# works with were designed with Java in mind, so it is most often compared with Java. Unlike Java, however, C# puts considerable effort into cross-platform interoperability through technologies such as unsafe code. C#'s basic data types follow the .NET object model, it provides runtime-level garbage collection, and it includes every element an object-oriented language should have, such as classes, interfaces, delegates, and exceptions.
Categories
- CSharp:Project - How to create a C# project.
- CSharp:Exception
- CSharp:Attributes - Things like
[Serializable]used right before a class, method, or member variable declaration - OpenCvSharp
- Windows Forms
- WPF
- WCF
- XAML
- AssemblyInfo.cs
System
- System.Diagnostics.Debug - Includes the
Assertstatement. - System.Drawing.Graphics
- System.IDisposable
- System.IO.Ports.SerialPort
- System.IO.Compression.ZipArchive
- Added a fix for when
ZipArchivecannot be found inSystem.IO.Compression.
- Added a fix for when
Syntax
.NET Categories
Examples
- Email:Eml2Msg - A C# program that converts the eml format to the msg format using the Aspose library.
Libraries
- Aspose
- XmlSchemaClassGenerator
- Github - sightreader/musicxml-schemas (MusicXmlSchema)
- Manufaktura Controls (Manufaktura.Controls, Manufaktura, ManufakturaLibraries)
- Godot:CSharp
- CSHTML5 - Plugin-Free .NET in your Browser by compiling C#/XAML to JavaScript/HTML
GUI Libraries
C Sharp syntax
Preprocessor directives
Region
Used to divide code into sections. Similar in purpose to #pragma mark in objc.
Hello, world!
using System;
namespace HelloWorld
{
class Program
{
private static void Main()
{
Console.WriteLine("Hello, world!");
}
}
}
String interpolation
See String interpolation for details.
string name = "Mark";
var date = DateTime.Now;
// Composite formatting:
Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
// Both calls produce the same output that is similar to:
// Hello, Mark! Today is Wednesday, it's 19:40 now.
Limiting decimal places
try ... catch ... when
When e.Data is null, the function re-throws InvalidCastException to the caller.
interface vs abstract
interface
public interface CallbackInterface
{
void OnRhythmComplete(int successCount, int failureCount, int readyCount);
void OnRhythmChangeCursor(int measureNumber, int beatNumber, float progressPercentage);
}
You can inherit (implement) more than one.
abstract
public abstract class BaseElementInterface
{
public abstract void OpenAttributeImpl(Xml.XmlNode node);
public abstract void OpenElementImpl(Xml.XmlNode node);
public abstract void ClearImpl();
public abstract string ToPrintableText();
public abstract string ToParamsText();
}
You can inherit only one.
Array Element Access Overload
Default Optional Parameter
Using the default keyword gives the default value of that variable. If you also want to name the variable default, you can use a form like @default to avoid the keyword conflict.
private Variant _Get(string section, string key, Variant @default = default /* `new Variant()` 와 동일하다. */ )
{
return _config.GetValue(section, key, @default);
}
const vs readonly
- C# constant keywords const vs readonly - Mentum
- const defines a compile-time constant.
- readonly defines a runtime constant.
internal
- internal - C# reference | Microsoft Learn
- The
internalkeyword is an access modifier for types and type members. - The
internalkeyword is also part of theprotected internalaccess modifier.
Internal types or members are accessible only within files in the same assembly, as in the following example.
Parsing a string into an Enum
public enum Colors { None=0, Red = 1, Green = 2, Blue = 4 };
// ...
Colors colorValue = (Colors) Enum.Parse(typeof(Colors), colorString, true);
Usage of the @ symbol
Putting the @ symbol before a string makes the escape characters in it ignored, so the string is taken literally. For example, when specifying a file path, a single backslash is treated as an escape character, so you use two backslashes; but if you put the @ symbol before the opening quote of the string, a backslash is taken as a backslash as is.
string filename = "C:\\Temp\\1.txt";
// @심벌을 사용하여 보다 자연스럽게 패스 지정
string filename = @"C:\Temp\1.txt";
// 여러 줄도 가능하다:
string code = @"
public string ReadFile(string filename)
{
if (!string.IsNullOrEmpty(filename))
{
return File.ReadAllText(filename);
}
return string.Empty;
}
";
Console.WriteLine(code);
Finally, the @ symbol is useful when put before a C# keyword so it can be used as an ordinary variable name. As the example below shows, object is a C# keyword, so you cannot write string object = "객체"; doing so causes a compile error. But if you put the @ sign before the C# keyword object, you can use it as a variable name. Still, just because this is possible, nobody recommends actually naming a variable object. On the contrary, most people recommend not using C# keywords as variable names.
public void Run()
{
// object라는 변수명 지정
string @object = "객체";
@object = @object + "1";
Console.WriteLine(@object);
}
So why is this feature needed?
Look at the example below. It shows an example of the Html Helper in ASP.NET MVC. The 4th parameter of the ActionLink method creates an object of an anonymous type and sets properties related to HTML attributes. Here, class is a C# keyword and cannot be used as a variable name, but the actual HTML attribute class is already defined by the standard, so it must be written as @class.
// ASP.NET MVC Html Helper
@Html.ActionLink("Goto Menu", "Menu", null,
new { @class="linkStyle", target="_blank"});
<A href="/Home/Menu" class="linkStyle" target="_blank">
Goto Menu
</A>
Property getter vs Method getter
public string MyProp { get; } - This was introduced in C# 6.0. Such properties are called read-only auto-properties. Assignment to such a member can occur only as part of the declaration or in a constructor of the same class. You can read a detailed explanation in the MSDN article or on Jon Skeet's blog. As explained in that article, such a property automatically solves the following four problems:
- A read-only-defined backing field
- Initialization of the backing field from within the constructor
- Explicit implementation of the property (rather than using an auto-property)
- An explicit getter implementation that returns the backing field
public string MyProp { get; private set; } - This means the property is read-only outside this class, but its value can be changed inside this class.
By the way, you can set the value of a read-only auto-property using the new auto-initializer syntax, also introduced in C# 6.0.
This is equivalent to the following code for earlier versions of C#:
private readonly string myProp = "You cannot change me"
public string MyProp { get { return myProp ; } }
Or this, in C# 6.0:
Is equivalent to the following in earlier versions.
private readonly string myProp;
public string MyProp { get { return myProp; } }
protected MyClass(string myProp, ...)
{
this.myProp = myProp;
...
}
Alternative methods for functional style
You should use Linq. Python's Map is Select:
Python's Reduce is Aggregate:
Python's Filter is Where:
Listing files
- Stackoverflow - How to recursively list all the files in a directory in C#?
- Stackoverflow - How to recursively list all the files in a directory in C#?
import System.IO;
// ...
foreach (string file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
Console.WriteLine(file);
}
Recursively listing directories:
static void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
{
Console.WriteLine(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
Folder Browser Dialog
- (C# syntax) Selecting a folder and getting its information with FolderBrowserDialog
- How to: Choose folders with the Windows Forms FolderBrowserDialog component
Creating in code:
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == DialogResult.OK)
{
// ...
}
Showing as a component:
public void ChooseFolder()
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = folderBrowserDialog1.SelectedPath;
}
}
Create file or directory
public class CreateFileOrFolder
{
static void Main()
{
// Specify a name for your top-level folder.
string folderName = @"c:\Top-Level Folder";
// To create a string that specifies the path to a subfolder under your
// top-level folder, add a name for the subfolder to folderName.
string pathString = System.IO.Path.Combine(folderName, "SubFolder");
// You can write out the path name directly instead of using the Combine
// method. Combine just makes the process easier.
string pathString2 = @"c:\Top-Level Folder\SubFolder2";
// You can extend the depth of your path if you want to.
//pathString = System.IO.Path.Combine(pathString, "SubSubFolder");
// Create the subfolder. You can verify in File Explorer that you have this
// structure in the C: drive.
// Local Disk (C:)
// Top-Level Folder
// SubFolder
System.IO.Directory.CreateDirectory(pathString);
// Create a file name for the file you want to create.
string fileName = System.IO.Path.GetRandomFileName();
// This example uses a random string for the name, but you also can specify
// a particular name.
//string fileName = "MyNewFile.txt";
// Use Combine again to add the file name to the path.
pathString = System.IO.Path.Combine(pathString, fileName);
// Verify the path that you have constructed.
Console.WriteLine("Path to my file: {0}\n", pathString);
// Check that the file doesn't already exist. If it doesn't exist, create
// the file and write integers 0 - 99 to it.
// DANGER: System.IO.File.Create will overwrite the file if it already exists.
// This could happen even with random file names, although it is unlikely.
if (!System.IO.File.Exists(pathString))
{
using (System.IO.FileStream fs = System.IO.File.Create(pathString))
{
for (byte i = 0; i < 100; i++)
{
fs.WriteByte(i);
}
}
}
else
{
Console.WriteLine("File \"{0}\" already exists.", fileName);
return;
}
// Read and display the data from your file.
try
{
byte[] readBuffer = System.IO.File.ReadAllBytes(pathString);
foreach (byte b in readBuffer)
{
Console.Write(b + " ");
}
Console.WriteLine();
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
}
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
// Sample output:
// Path to my file: c:\Top-Level Folder\SubFolder\ttxvauxe.vv0
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
//30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
// 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 8
//3 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
}
Lock
MemoryStream and StringWriter
// ...
public string GetIdentificationText()
{
using (MemoryStream stream = new MemoryStream())
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.WriteLine("[Identification]");
foreach (var right in _scorePartwise.Identification.Rights)
{
writer.WriteLine($"- Right: {right.Value}");
}
var encoding = _scorePartwise.Identification.Encoding;
foreach (var encoder in encoding.Encoder)
{
writer.WriteLine($"- Encoder: {encoder.Value}");
}
foreach (var encodingDate in encoding.EncodingDate)
{
writer.WriteLine($"- Encoding Date: {encodingDate}");
}
foreach (var encodingDescription in encoding.EncodingDescription)
{
writer.WriteLine($"- Encoding Description: {encodingDescription}");
}
foreach (var software in encoding.Software)
{
writer.WriteLine($"- Software: {software}");
}
foreach (var supports in encoding.Supports)
{
var e = supports.Element;
var t = supports.Type;
var v = supports.Value;
var a = supports.Attribute;
writer.WriteLine($"- Software: element={e}, type={t}, value={v}, attribute={a}");
}
}
return System.Text.Encoding.UTF8.GetString(stream.ToArray());
}
}
// ...
Syntax
Array & Rank
An array has a dimension (Rank), indices (Index), and values (Element).
An example of multidimensional arrays and how to inspect them is shown below.
// Two-dimensional array.
int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// The same array with dimensions specified.
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// A similar array with string elements.
string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },
{ "five", "six" } };
// Three-dimensional array.
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// The same array with dimensions specified.
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
for (int i = 0; i < array3D.Rank; i++) {
total *= array3D.GetLength(i);
}
Note that when you pass a lower Index value as the parameter to GetLength, it returns the length of a higher-order dimension.
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
array2Da.GetLength(0); // Return 4
array2Da.GetLength(1); // Return 2
Random
Random r = new Random();
r.Next(); // 랜덤값 생성
r.Next(Int32 min, Int32 max); // 최소 min 값 부터 최대 max - 1 까지
Running a single C# file directly
- Starting with .NET 10 Preview 4, a single C# file can now be run directly with dotnet run app.cs, so C# code can run without a project file
- File-based apps make simple script execution, testing, and trying out ideas much easier, as in Python or JavaScript
- NuGet package references, SDK selection, build property settings, and more can also be managed with directives inside the file, improving development flexibility
- Shebang support makes it usable for CLI utilities, automation scripts, and more on Unix-like systems
- It can be smoothly converted into a project-based app when needed, so it connects naturally from learning and prototyping to full-scale app development
See also
Favorite site
- C# documentation - Get started, tutorials, reference. | Microsoft Docs
- MSDN Visual C#
- MSDN C# Keywords
- C# programming guide
- Wikipedia (en) description of C#
- Creating a tray icon in C#
- Displaying images in a ListView in C#
- Saving to the clipboard in C#
- C# function to get the list of files inside subfolders
Tutorials
Demo
- ASP.NET
- Aspose
- AssemblyInfo.cs
- Bezier curve
- Blazor
- C++
- Computer Language
- CSharp:Attributes
- CSharp:ConfigurationManager
- CSharp:Exception
- CSharp:Project
- CSharp:using
- Dotnet
- Email:Eml2Msg
- Game Engine
- Godot.Reference
- Godot:CSharp
- Godot:Export:iOS
- Godot:NodePath
- Godot:Plugins
- Godot:XMLParser
- Graphical user interface
- Language Integrated Query
- Large language model
- MemoryPack
- MessagePack
- Mono
- MonoGame
- Msbuild
- Musical Instrument Digital Interface
- MusicXml.NET
- NuGet
- OmniSharp
- OpenCvSharp
- Programming language
- Programming:Basic
- Razor
- Routing engine
- Semantic Kernel
- Serialization
- System.Diagnostics.Debug
- System.IDisposable
- System.IO.Compression.ZipArchive
- System.IO.Ports.SerialPort
- System.Text.Encoding
- System.Windows.Forms.TextBox
- XCode
- XmlSchemaClassGenerator