C#で値を取得する方法まとめ|文字列・配列・JSON・DBから安全に取り出す基本と実践
はじめに
C#でプログラムを書くとき、「値を取得する」処理はほぼすべての場面で登場します。文字列から一部を取り出す、配列やListから要素を取得する、Dictionaryからキーに対応する値を取得する、JSONやデータベースから必要なデータを読み取るなど、C#における「取得」は非常に幅広い意味を持ちます。
一方で、値の取得処理はエラーも起こりやすい部分です。たとえば、存在しない配列のインデックスを指定するとIndexOutOfRangeExceptionが発生します。nullのオブジェクトからプロパティを取得しようとするとNullReferenceExceptionが発生します。Dictionaryに存在しないキーを指定すればKeyNotFoundExceptionが発生することもあります。
この記事では、「c# 取得」というテーマで、C#で値を取得する基本から実践的な書き方までをまとめて解説します。文字列、配列、List、Dictionary、オブジェクト、JSON、データベース、ファイル、設定値、入力値など、よく使う取得パターンを一通り確認しながら、安全で読みやすいコードを書くためのポイントを紹介します。
1. C#で「値を取得する」とは?まず押さえる基本
1-1. C#における「取得」の意味と主な対象
C#で「取得する」とは、プログラム内や外部データから必要な値を取り出して利用することを指します。取得対象はさまざまで、代表的なものには次のようなものがあります。
C#string name = "Taro";
int age = 30;
Console.WriteLine(name);
Console.WriteLine(age);
この例では、変数nameやageに格納された値を取得して、Console.WriteLineで表示しています。とても単純な処理ですが、これもC#における値の取得です。
実際の開発では、次のような対象から値を取得することが多くあります。
C#// 文字列から取得
string text = "ABC-123";
string code = text.Substring(4);
// 配列から取得
int[] numbers = { 10, 20, 30 };
int first = numbers[0];
// Dictionaryから取得
var scores = new Dictionary<string, int>
{
{ "Alice", 90 },
{ "Bob", 80 }
};
int aliceScore = scores["Alice"];
// オブジェクトのプロパティから取得
var user = new User { Name = "Yamada" };
string userName = user.Name;
C#で値を取得する場面では、「どこから」「どの型で」「安全に取得できるか」を意識することが重要です。
1-2. 変数・プロパティ・メソッド戻り値から値を取得する基本
C#で最も基本的な値の取得は、変数から値を読み出すことです。
C#int count = 10;
int result = count;
この場合、countに入っている10を取得し、resultに代入しています。
プロパティから値を取得する場合は、オブジェクト名とプロパティ名をドットでつなぎます。
C#public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
var user = new User
{
Name = "Sato",
Age = 25
};
string name = user.Name;
int age = user.Age;
メソッドの戻り値を取得する場合は、メソッドを呼び出して戻り値を変数に代入します。
C#int GetPrice()
{
return 1200;
}
int price = GetPrice();
このように、C#では変数、プロパティ、メソッド戻り値の取得が基本になります。複雑な処理でも、最終的にはこれらの組み合わせで値を取得していきます。
1-3. 値型と参照型で取得時に注意すべき違い
C#には大きく分けて値型と参照型があります。値を取得するときは、この違いを理解しておくことが大切です。
値型には、int、double、bool、DateTime、structなどがあります。値型は基本的に値そのものを扱います。
C#int a = 10;
int b = a;
b = 20;
Console.WriteLine(a); // 10
Console.WriteLine(b); // 20
b = aで値を取得して代入していますが、bを変更してもaには影響しません。
一方、参照型には、string、配列、クラス、List、Dictionaryなどがあります。参照型はオブジェクトへの参照を扱います。
C#var user1 = new User { Name = "Tanaka" };
var user2 = user1;
user2.Name = "Suzuki";
Console.WriteLine(user1.Name); // Suzuki
Console.WriteLine(user2.Name); // Suzuki
この例では、user2にuser1の参照が代入されます。そのため、user2.Nameを変更すると、同じオブジェクトを参照しているuser1.Nameにも影響します。
値を取得したつもりでも、参照型では同じオブジェクトを共有している場合があります。取得後に値を変更する処理では、値型と参照型の違いを意識しましょう。
1-4. null・例外・型変換を意識した安全な取得の考え方
C#で値を取得するときは、単に値を取り出すだけでなく、安全に取得することが重要です。特に注意すべきなのは、null、例外、型変換です。
たとえば、次のコードはuserがnullの場合にNullReferenceExceptionが発生します。
C#User user = null;
string name = user.Name; // 例外
安全に取得するには、nullチェックやnull条件演算子を使います。
C#string name = user?.Name;
user?.Nameと書くと、userがnullの場合は例外を発生させず、結果としてnullを返します。
また、文字列を数値に変換して取得する場合は、int.Parseではなくint.TryParseを使うと安全です。
C#string input = "123";
if (int.TryParse(input, out int number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("数値に変換できません");
}
値の取得では、「値が存在する前提」で書くとエラーが起きやすくなります。存在しない可能性、nullの可能性、型変換に失敗する可能性を考慮して実装することが、C#で安全に値を取得する基本です。
2. 文字列から値を取得する方法
2-1. 文字列の一部を取得する:Substring・Range・Index
C#で文字列の一部を取得する代表的な方法はSubstringです。
C#string text = "Hello World";
string part = text.Substring(0, 5);
Console.WriteLine(part); // Hello
Substring(0, 5)は、インデックス0から5文字分を取得します。C#の文字列インデックスは0から始まるため、最初の文字はtext[0]です。
開始位置だけを指定すると、その位置から末尾まで取得できます。
C#string text = "ABC-12345";
string number = text.Substring(4);
Console.WriteLine(number); // 12345
C# 8.0以降では、Rangeを使って文字列の一部を取得することもできます。
C#string text = "Hello World";
string hello = text[..5];
string world = text[6..];
Console.WriteLine(hello); // Hello
Console.WriteLine(world); // World
末尾から位置を指定したい場合は、^を使います。
C#string text = "file.txt";
string extension = text[^3..];
Console.WriteLine(extension); // txt
ただし、SubstringやRangeは範囲を誤ると例外が発生します。文字列の長さを確認してから取得するのが安全です。
C#string text = "ABC";
if (text.Length >= 2)
{
string part = text.Substring(0, 2);
Console.WriteLine(part);
}
2-2. 1文字だけ取得する:インデックス指定と範囲外エラー対策
文字列から1文字だけ取得する場合は、インデックスを指定します。
C#string text = "CSharp";
char first = text[0];
Console.WriteLine(first); // C
2文字目を取得する場合はtext[1]です。
C#char second = text[1];
Console.WriteLine(second); // S
注意点は、存在しないインデックスを指定するとIndexOutOfRangeExceptionが発生することです。
C#string text = "ABC";
char value = text[5]; // 例外
安全に取得するには、文字列の長さを確認します。
C#string text = "ABC";
int index = 2;
if (!string.IsNullOrEmpty(text) && index >= 0 && index < text.Length)
{
char value = text[index];
Console.WriteLine(value);
}
else
{
Console.WriteLine("指定した位置の文字は取得できません");
}
文字列から値を取得するときは、インデックスが0以上で、文字列の長さ未満であることを確認するのが基本です。
2-3. 特定文字で分割して取得する:Splitの基本
文字列を区切り文字で分割して値を取得する場合は、Splitを使います。
C#string csv = "apple,banana,orange";
string[] fruits = csv.Split(',');
Console.WriteLine(fruits[0]); // apple
Console.WriteLine(fruits[1]); // banana
Console.WriteLine(fruits[2]); // orange
CSVのようにカンマ区切りの文字列から値を取得するときによく使います。
空白を取り除きたい場合は、Trimと組み合わせます。
C#string csv = "apple, banana, orange";
string[] fruits = csv.Split(',');
foreach (string fruit in fruits)
{
Console.WriteLine(fruit.Trim());
}
分割後に特定の位置の値を取得する場合は、配列の要素数を確認しましょう。
C#string data = "100:Tanaka";
string[] parts = data.Split(':');
if (parts.Length >= 2)
{
string id = parts[0];
string name = parts[1];
Console.WriteLine(id);
Console.WriteLine(name);
}
Splitは便利ですが、想定した区切り文字が存在しない場合でも配列は返ります。そのため、parts[1]のように取得する前に、必ずLengthを確認することが安全です。
2-4. 条件に合う文字列を探して取得する:Contains・IndexOf・Regex
文字列の中に特定の文字列が含まれているか確認するにはContainsを使います。
C#string text = "C#で値を取得する方法";
bool exists = text.Contains("取得");
Console.WriteLine(exists); // True
特定の文字列が何文字目にあるか取得したい場合はIndexOfを使います。
C#string text = "ABC-12345";
int index = text.IndexOf("-");
Console.WriteLine(index); // 3
IndexOfは、見つからない場合に-1を返します。取得処理に使う場合は、-1でないことを確認しましょう。
C#string text = "ABC-12345";
int index = text.IndexOf("-");
if (index >= 0)
{
string before = text.Substring(0, index);
string after = text.Substring(index + 1);
Console.WriteLine(before); // ABC
Console.WriteLine(after); // 12345
}
より複雑な条件で文字列を取得したい場合は、正規表現を使います。
C#using System.Text.RegularExpressions;
string text = "注文番号: ABC-12345";
Match match = Regex.Match(text, @"[A-Z]{3}-\d{5}");
if (match.Success)
{
string orderNo = match.Value;
Console.WriteLine(orderNo); // ABC-12345
}
Regex.Matchを使うと、パターンに一致した文字列だけを取得できます。ログ解析、入力チェック、コード抽出などで便利です。
2-5. 空文字・nullを安全に扱うチェック方法
文字列から値を取得する前には、nullや空文字を確認することが大切です。
C#string text = null;
if (!string.IsNullOrEmpty(text))
{
Console.WriteLine(text.Substring(0, 1));
}
else
{
Console.WriteLine("文字列がnullまたは空です");
}
string.IsNullOrEmptyは、文字列がnullまたは空文字の場合にtrueを返します。
空白だけの文字列も無効としたい場合は、string.IsNullOrWhiteSpaceを使います。
C#string text = " ";
if (!string.IsNullOrWhiteSpace(text))
{
Console.WriteLine(text.Trim());
}
else
{
Console.WriteLine("文字列が未入力です");
}
ユーザー入力や外部ファイルから取得した文字列は、null、空文字、空白のみの可能性があります。文字列から値を取得する前にチェックを入れることで、例外や意図しない処理を防げます。
3. 配列・List・Dictionaryから値を取得する方法
3-1. 配列からインデックスで値を取得する
配列から値を取得する基本は、インデックス指定です。
C#int[] numbers = { 10, 20, 30 };
int first = numbers[0];
int second = numbers[1];
Console.WriteLine(first); // 10
Console.WriteLine(second); // 20
C#の配列は0から始まります。最後の要素はLength - 1で取得できます。
C#int[] numbers = { 10, 20, 30 };
int last = numbers[numbers.Length - 1];
Console.WriteLine(last); // 30
ただし、空配列の場合にnumbers[numbers.Length - 1]を実行すると例外が発生します。安全に取得するには、要素数を確認しましょう。
C#int[] numbers = { 10, 20, 30 };
if (numbers.Length > 0)
{
int last = numbers[numbers.Length - 1];
Console.WriteLine(last);
}
範囲外のインデックスを指定するとIndexOutOfRangeExceptionが発生します。
C#int[] numbers = { 10, 20, 30 };
int value = numbers[5]; // 例外
安全に値を取得するには、インデックスが0以上かつLength未満であることを確認します。
C#int index = 1;
if (index >= 0 && index < numbers.Length)
{
int value = numbers[index];
Console.WriteLine(value);
}
3-2. Listから値を取得する:ElementAt・First・Find
List<T>から値を取得する場合も、配列と同じようにインデックスを指定できます。
C#var names = new List<string> { "Alice", "Bob", "Charlie" };
string first = names[0];
Console.WriteLine(first); // Alice
LINQのElementAtを使って取得することもできます。
C#using System.Linq;
var names = new List<string> { "Alice", "Bob", "Charlie" };
string name = names.ElementAt(1);
Console.WriteLine(name); // Bob
ただし、ElementAtも範囲外の場合は例外が発生します。安全に取得したい場合はElementAtOrDefaultを使います。
C#string name = names.ElementAtOrDefault(10);
if (name != null)
{
Console.WriteLine(name);
}
else
{
Console.WriteLine("指定した要素は存在しません");
}
最初の要素を取得する場合はFirstを使います。
C#var numbers = new List<int> { 10, 20, 30 };
int first = numbers.First();
Console.WriteLine(first); // 10
空のListでFirstを使うと例外が発生するため、安全に取得したい場合はFirstOrDefaultを使います。
C#var numbers = new List<int>();
int first = numbers.FirstOrDefault();
Console.WriteLine(first); // 0
条件に一致する値を取得したい場合はFindが便利です。
C#var users = new List<User>
{
new User { Name = "Alice", Age = 20 },
new User { Name = "Bob", Age = 30 }
};
User user = users.Find(u => u.Name == "Bob");
if (user != null)
{
Console.WriteLine(user.Age); // 30
}
3-3. Dictionaryからキーで値を取得する
Dictionary<TKey, TValue>は、キーを指定して値を取得するコレクションです。
C#var scores = new Dictionary<string, int>
{
{ "Alice", 90 },
{ "Bob", 80 }
};
int score = scores["Alice"];
Console.WriteLine(score); // 90
Dictionaryは、キーと値の組み合わせでデータを管理したい場合に便利です。
C#var settings = new Dictionary<string, string>
{
{ "Theme", "Dark" },
{ "Language", "ja" }
};
string theme = settings["Theme"];
Console.WriteLine(theme); // Dark
ただし、存在しないキーを指定するとKeyNotFoundExceptionが発生します。
C#string value = settings["FontSize"]; // 例外
キーが存在するか確認するには、ContainsKeyを使います。
C#if (settings.ContainsKey("Theme"))
{
string value = settings["Theme"];
Console.WriteLine(value);
}
ただし、ContainsKeyで確認したあとに再度キーで値を取得すると、Dictionaryを2回検索することになります。より実践的にはTryGetValueを使うのがおすすめです。
3-4. TryGetValueでキー不存在時の例外を防ぐ
Dictionaryから安全に値を取得するには、TryGetValueを使います。
C#var scores = new Dictionary<string, int>
{
{ "Alice", 90 },
{ "Bob", 80 }
};
if (scores.TryGetValue("Alice", out int score))
{
Console.WriteLine(score);
}
else
{
Console.WriteLine("キーが存在しません");
}
TryGetValueは、キーが存在する場合はtrueを返し、値をout変数に格納します。キーが存在しない場合はfalseを返すため、例外を防げます。
文字列のDictionaryでも同じです。
C#var userMap = new Dictionary<int, string>
{
{ 1, "Tanaka" },
{ 2, "Suzuki" }
};
if (userMap.TryGetValue(2, out string name))
{
Console.WriteLine(name); // Suzuki
}
値が存在しない場合にデフォルト値を使いたい場合は、次のように書けます。
C#string displayName = userMap.TryGetValue(3, out string name)
? name
: "未登録";
Console.WriteLine(displayName); // 未登録
C#でDictionaryから値を取得する場合、基本的にはTryGetValueを使うと安全で読みやすいコードになります。
3-5. LINQで条件に一致する値を取得する
配列やListから条件に一致する値を取得する場合は、LINQが便利です。
C#using System.Linq;
var numbers = new List<int> { 10, 20, 30, 40 };
int value = numbers.First(n => n >= 30);
Console.WriteLine(value); // 30
ただし、条件に一致する要素が存在しない場合、Firstは例外を発生させます。安全に取得したい場合はFirstOrDefaultを使います。
C#int value = numbers.FirstOrDefault(n => n >= 100);
Console.WriteLine(value); // 0
参照型の場合は、見つからなければnullになります。
C#var users = new List<User>
{
new User { Name = "Alice", Age = 20 },
new User { Name = "Bob", Age = 30 }
};
User user = users.FirstOrDefault(u => u.Name == "Charlie");
if (user == null)
{
Console.WriteLine("ユーザーが見つかりません");
}
複数の値を取得したい場合はWhereを使います。
C#var adults = users.Where(u => u.Age >= 20).ToList();
foreach (var adult in adults)
{
Console.WriteLine(adult.Name);
}
条件に合う値を1件取得したいのか、複数件取得したいのかによって、FirstOrDefault、SingleOrDefault、Whereを使い分けましょう。
4. オブジェクト・クラス・プロパティから値を取得する方法
4-1. インスタンスのプロパティ値を取得する基本
C#でクラスのインスタンスから値を取得する場合は、プロパティを使います。
C#public class Product
{
public string Name { get; set; }
public int Price { get; set; }
}
var product = new Product
{
Name = "Keyboard",
Price = 5000
};
string name = product.Name;
int price = product.Price;
Console.WriteLine(name);
Console.WriteLine(price);
product.Nameやproduct.Priceのように、インスタンス名とプロパティ名をドットでつなぐことで値を取得できます。
プロパティは、オブジェクトの状態を外部から取得するための一般的な仕組みです。クラスを設計するときは、外部に公開したい値をプロパティとして定義します。
4-2. getアクセサを使った値の取得
C#のプロパティにはgetアクセサとsetアクセサがあります。getは値を取得するため、setは値を設定するためのアクセサです。
C#public class User
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
このクラスでは、Nameプロパティからnameフィールドの値を取得できます。
C#var user = new User();
user.Name = "Yamada";
string name = user.Name;
Console.WriteLine(name); // Yamada
読み取り専用のプロパティを作りたい場合は、getだけを定義します。
C#public class Tax
{
public decimal Rate
{
get
{
return 0.1m;
}
}
}
短く書く場合は、式形式のプロパティも使えます。
C#public class Tax
{
public decimal Rate => 0.1m;
}
getアクセサを使うことで、内部の値を直接公開せず、必要な形式で値を取得させることができます。
4-3. privateフィールドの値を安全に公開する方法
クラス内のprivateフィールドは、外部から直接取得できません。
C#public class User
{
private string name = "Tanaka";
}
この場合、外部からuser.nameのようにアクセスすることはできません。値を取得させたい場合は、プロパティやメソッドを用意します。
C#public class User
{
private string name = "Tanaka";
public string Name
{
get
{
return name;
}
}
}
使う側は次のように値を取得します。
C#var user = new User();
string name = user.Name;
Console.WriteLine(name); // Tanaka
メソッドで取得させることもできます。
C#public class User
{
private string name = "Tanaka";
public string GetName()
{
return name;
}
}
C#var user = new User();
string name = user.GetName();
Console.WriteLine(name);
基本的には、単純な値の取得にはプロパティを使い、何らかの処理や計算を伴う場合はメソッドを使うと分かりやすくなります。
4-4. null条件演算子でオブジェクトの値を安全に取得する
オブジェクトがnullの可能性がある場合は、null条件演算子?.を使うと安全に値を取得できます。
C#User user = null;
string name = user?.Name;
Console.WriteLine(name); // null
通常、user.Nameと書くと、userがnullの場合にNullReferenceExceptionが発生します。しかし、user?.Nameと書くと、userがnullなら結果もnullになります。
さらに、null合体演算子??と組み合わせると、デフォルト値を設定できます。
C#string name = user?.Name ?? "未設定";
Console.WriteLine(name); // 未設定
ネストしたオブジェクトから値を取得する場合にも便利です。
C#string city = user?.Address?.City ?? "住所未設定";
このように書くことで、userやAddressがnullでも例外を発生させずに値を取得できます。C#でオブジェクトの値を安全に取得するうえで、?.と??は非常によく使う演算子です。
4-5. 動的なプロパティ取得とリフレクションの注意点
プロパティ名を文字列で指定して値を取得したい場合は、リフレクションを使えます。
C#using System.Reflection;
var user = new User
{
Name = "Sato",
Age = 25
};
PropertyInfo property = typeof(User).GetProperty("Name");
if (property != null)
{
object value = property.GetValue(user);
Console.WriteLine(value);
}
リフレクションを使うと、実行時にプロパティ情報を取得できます。設定ファイルや汎用的なマッピング処理などで使われることがあります。
ただし、リフレクションには注意点があります。通常のプロパティアクセスよりもコードが分かりにくくなり、型安全性も弱くなります。また、プロパティ名を文字列で指定するため、名前を間違えてもコンパイル時に検出できません。
C#PropertyInfo property = typeof(User).GetProperty("Nam"); // タイプミス
この場合、propertyはnullになります。
リフレクションは便利ですが、通常の開発ではまず通常のプロパティアクセスを使い、必要な場合だけリフレクションを検討するとよいでしょう。
5. JSONから値を取得する方法
5-1. System.Text.JsonでJSONを読み取る基本
C#でJSONから値を取得する場合、標準ライブラリのSystem.Text.Jsonを使う方法が一般的です。
C#using System.Text.Json;
string json = """
{
"name": "Tanaka",
"age": 30
}
""";
このJSONから値を取得する方法には、大きく分けて2つあります。
1つは、JsonDocumentを使ってキーを指定しながら値を取得する方法です。もう1つは、JsonSerializerでクラスに変換してからプロパティとして取得する方法です。
小さなJSONや一部の値だけを取得したい場合はJsonDocumentが便利です。構造が決まっているJSONを扱う場合は、クラスに変換する方法が読みやすくなります。
5-2. JsonDocumentで特定キーの値を取得する
JsonDocumentを使うと、JSONの中から特定のキーの値を取得できます。
C#using System.Text.Json;
string json = """
{
"name": "Tanaka",
"age": 30
}
""";
using JsonDocument document = JsonDocument.Parse(json);
JsonElement root = document.RootElement;
string name = root.GetProperty("name").GetString();
int age = root.GetProperty("age").GetInt32();
Console.WriteLine(name); // Tanaka
Console.WriteLine(age); // 30
GetProperty("name")でnameキーの値を取得し、GetString()で文字列として取り出しています。数値の場合はGetInt32()などを使います。
ただし、存在しないキーをGetPropertyで取得しようとすると例外が発生します。安全に取得するにはTryGetPropertyを使います。
C#if (root.TryGetProperty("name", out JsonElement nameElement))
{
string name = nameElement.GetString();
Console.WriteLine(name);
}
else
{
Console.WriteLine("nameキーが存在しません");
}
JSONから値を取得する場合は、キーが必ず存在するとは限らないことを考慮して実装しましょう。
5-3. JsonSerializerでクラスに変換して値を取得する
JSONの構造が決まっている場合は、クラスを定義してJsonSerializer.Deserializeで変換すると扱いやすくなります。
C#using System.Text.Json;
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
JSONのプロパティ名がnameやageのように小文字の場合、属性を使って対応させることもできます。
C#using System.Text.Json.Serialization;
public class User
{
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("age")]
public int Age { get; set; }
}
取得処理は次のように書きます。
C#string json = """
{
"name": "Tanaka",
"age": 30
}
""";
User user = JsonSerializer.Deserialize<User>(json);
if (user != null)
{
Console.WriteLine(user.Name);
Console.WriteLine(user.Age);
}
クラスに変換すると、user.Nameのように通常のプロパティとして値を取得できます。APIレスポンスや設定ファイルなど、構造が決まっているJSONを扱う場合におすすめです。
5-4. 配列形式のJSONから複数の値を取得する
JSONが配列形式の場合も、JsonDocumentやJsonSerializerで値を取得できます。
C#string json = """
[
{ "name": "Alice", "age": 20 },
{ "name": "Bob", "age": 30 }
]
""";
JsonDocumentで取得する場合は、EnumerateArrayを使います。
C#using JsonDocument document = JsonDocument.Parse(json);
foreach (JsonElement item in document.RootElement.EnumerateArray())
{
string name = item.GetProperty("name").GetString();
int age = item.GetProperty("age").GetInt32();
Console.WriteLine($"{name}: {age}");
}
クラスに変換する場合は、List<User>にデシリアライズします。
C#List<User> users = JsonSerializer.Deserialize<List<User>>(json);
if (users != null)
{
foreach (User user in users)
{
Console.WriteLine($"{user.Name}: {user.Age}");
}
}
配列形式のJSONから複数の値を取得する場合は、クラスに変換したほうが後続処理を書きやすくなることが多いです。
5-5. キーが存在しない場合やnull値への安全な対処法
JSONから値を取得するときは、キーが存在しない場合や値がnullの場合を考慮しましょう。
JsonDocumentでは、TryGetPropertyを使うとキーの存在確認ができます。
C#if (root.TryGetProperty("email", out JsonElement emailElement)
&& emailElement.ValueKind != JsonValueKind.Null)
{
string email = emailElement.GetString();
Console.WriteLine(email);
}
else
{
Console.WriteLine("emailは存在しないかnullです");
}
数値を取得する場合も、型が想定どおりか確認すると安全です。
C#if (root.TryGetProperty("age", out JsonElement ageElement)
&& ageElement.ValueKind == JsonValueKind.Number)
{
int age = ageElement.GetInt32();
Console.WriteLine(age);
}
JsonSerializerでクラスに変換する場合は、プロパティがnullになる可能性があります。
C#User user = JsonSerializer.Deserialize<User>(json);
string name = user?.Name ?? "名前未設定";
外部APIのJSONは、仕様変更やデータ不足によってキーが存在しない場合があります。JSONから値を取得するときは、存在確認とnullチェックをセットで考えることが重要です。
6. データベースから値を取得する方法
6-1. C#でDBから値を取得する基本の流れ
C#でデータベースから値を取得する基本の流れは、次のようになります。
C#// 1. 接続文字列を用意する
// 2. DB接続を開く
// 3. SQLを実行する
// 4. 結果を取得する
// 5. 接続を閉じる
SQL Serverを使う場合は、SqlConnection、SqlCommand、SqlDataReaderなどを使います。
C#using Microsoft.Data.SqlClient;
または環境によっては、System.Data.SqlClientを使う場合もあります。
データベースから値を取得するときは、SQLインジェクションを防ぐために、文字列連結ではなくパラメーターを使うことが重要です。
悪い例は次のような書き方です。
C#string sql = "SELECT Name FROM Users WHERE Id = " + id;
安全な書き方は次のようにパラメーターを使います。
C#string sql = "SELECT Name FROM Users WHERE Id = @Id";
DBから値を取得する処理では、接続管理、パラメーター、null、型変換、例外処理を意識して実装しましょう。
6-2. SqlCommand・SqlDataReaderで値を取得する
複数行のデータを取得する場合は、SqlDataReaderを使います。
C#using Microsoft.Data.SqlClient;
string connectionString = "接続文字列";
string sql = "SELECT Id, Name FROM Users WHERE IsActive = @IsActive";
using var connection = new SqlConnection(connectionString);
using var command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@IsActive", true);
connection.Open();
using SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
int id = reader.GetInt32(reader.GetOrdinal("Id"));
string name = reader.GetString(reader.GetOrdinal("Name"));
Console.WriteLine($"{id}: {name}");
}
reader.Read()は、次の行が存在する場合にtrueを返します。各列の値は、GetInt32やGetStringなどで取得します。
列番号で取得することもできます。
C#int id = reader.GetInt32(0);
string name = reader.GetString(1);
ただし、列順が変わると不具合になりやすいため、列名からGetOrdinalで列番号を取得する方法が使われることもあります。
C#int nameIndex = reader.GetOrdinal("Name");
string name = reader.GetString(nameIndex);
DBの値がnullの場合、GetStringなどをそのまま使うと例外が発生することがあります。nullの可能性がある列はIsDBNullで確認しましょう。
C#int emailIndex = reader.GetOrdinal("Email");
string email = reader.IsDBNull(emailIndex)
? ""
: reader.GetString(emailIndex);
6-3. ExecuteScalarで単一の値を取得する
SQLの結果が1つの値だけでよい場合は、ExecuteScalarが便利です。たとえば、件数を取得する場合に使います。
C#using Microsoft.Data.SqlClient;
string connectionString = "接続文字列";
string sql = "SELECT COUNT(*) FROM Users";
using var connection = new SqlConnection(connectionString);
using var command = new SqlCommand(sql, connection);
connection.Open();
object result = command.ExecuteScalar();
int count = Convert.ToInt32(result);
Console.WriteLine(count);
特定ユーザーの名前を1件だけ取得する場合も使えます。
C#string sql = "SELECT Name FROM Users WHERE Id = @Id";
using var connection = new SqlConnection(connectionString);
using var command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@Id", 1);
connection.Open();
object result = command.ExecuteScalar();
string name = result == null || result == DBNull.Value
? ""
: Convert.ToString(result);
Console.WriteLine(name);
ExecuteScalarは、最初の行の最初の列だけを取得します。単一値を取得したい場合にはシンプルですが、複数列や複数行を扱う場合はSqlDataReaderやORMを使いましょう。
6-4. DataTableやEntity Frameworkで値を取得する
DataTableを使って値を取得する場合は、行と列を指定します。
C#DataTable table = new DataTable();
// 例: tableにデータが入っている前提
if (table.Rows.Count > 0)
{
object value = table.Rows[0]["Name"];
string name = value == DBNull.Value ? "" : value.ToString();
Console.WriteLine(name);
}
DataTableでは、DBのnullがDBNull.Valueとして扱われる点に注意が必要です。
Entity Frameworkを使う場合は、LINQで値を取得できます。
C#using var context = new AppDbContext();
var user = context.Users
.FirstOrDefault(u => u.Id == 1);
if (user != null)
{
Console.WriteLine(user.Name);
}
複数件取得する場合はWhereやToListを使います。
C#var activeUsers = context.Users
.Where(u => u.IsActive)
.ToList();
foreach (var user in activeUsers)
{
Console.WriteLine(user.Name);
}
Entity Frameworkを使うと、SQLを直接書かずにオブジェクトとして値を取得できます。ただし、どのタイミングでSQLが実行されるか、必要以上にデータを取得していないかには注意しましょう。
6-5. DBNull・null・型変換エラーを防ぐ実装ポイント
DBから値を取得するときに特に注意すべきなのが、DBNullです。C#のnullとDBのNULLは扱いが異なり、DataReaderやDataTableではDBのNULLがDBNull.Valueとして返されます。
SqlDataReaderの場合は、IsDBNullで確認します。
C#int index = reader.GetOrdinal("Birthday");
DateTime? birthday = reader.IsDBNull(index)
? null
: reader.GetDateTime(index);
DataTableの場合は、DBNull.Valueと比較します。
C#object value = row["Birthday"];
DateTime? birthday = value == DBNull.Value
? null
: Convert.ToDateTime(value);
型変換エラーを防ぐには、取得する列の型とC#側の型を合わせることが重要です。
C#int age = reader.GetInt32(reader.GetOrdinal("Age"));
DB側がbigintならC#ではlong、decimalならdecimal、datetimeならDateTimeのように、適切な型で取得しましょう。
文字列として取得した値を数値に変換する場合は、TryParseを使うと安全です。
C#string ageText = Convert.ToString(row["Age"]);
if (int.TryParse(ageText, out int age))
{
Console.WriteLine(age);
}
DB取得処理では、値が存在するか、NULLではないか、型が一致しているかを確認することで、実行時エラーを大きく減らせます。
7. ファイル・設定値・入力値から値を取得する方法
7-1. テキストファイルから値を読み取る
C#でテキストファイルから値を取得するには、File.ReadAllTextやFile.ReadAllLinesを使います。
ファイル全体を文字列として取得する場合は、ReadAllTextを使います。
C#using System.IO;
string text = File.ReadAllText("sample.txt");
Console.WriteLine(text);
行ごとに取得したい場合は、ReadAllLinesを使います。
C#string[] lines = File.ReadAllLines("sample.txt");
foreach (string line in lines)
{
Console.WriteLine(line);
}
1行ずつ処理したい場合は、File.ReadLinesが便利です。
C#foreach (string line in File.ReadLines("sample.txt"))
{
Console.WriteLine(line);
}
ファイルが存在しない場合は例外が発生するため、事前に確認すると安全です。
C#string path = "sample.txt";
if (File.Exists(path))
{
string text = File.ReadAllText(path);
Console.WriteLine(text);
}
else
{
Console.WriteLine("ファイルが存在しません");
}
ファイルから値を取得する処理では、ファイルの存在、文字コード、空ファイル、読み取り権限などにも注意しましょう。
7-2. appsettings.jsonから設定値を取得する
ASP.NET Coreなどでは、appsettings.jsonから設定値を取得する場面がよくあります。
たとえば、次のような設定ファイルがあるとします。
JSON{
"AppSettings": {
"SiteName": "MySite",
"MaxItems": 100
}
}
設定値を取得するには、IConfigurationを使います。
C#public class SampleService
{
private readonly IConfiguration _configuration;
public SampleService(IConfiguration configuration)
{
_configuration = configuration;
}
public void ShowSettings()
{
string siteName = _configuration["AppSettings:SiteName"];
int maxItems = _configuration.GetValue<int>("AppSettings:MaxItems");
Console.WriteLine(siteName);
Console.WriteLine(maxItems);
}
}
文字列として取得する場合は、キーを指定して取得できます。
C#string siteName = _configuration["AppSettings:SiteName"];
型を指定して取得する場合は、GetValue<T>が便利です。
C#int maxItems = _configuration.GetValue<int>("AppSettings:MaxItems");
設定項目をクラスにバインドして取得する方法もあります。
C#public class AppSettings
{
public string SiteName { get; set; }
public int MaxItems { get; set; }
}
C#var settings = _configuration
.GetSection("AppSettings")
.Get<AppSettings>();
if (settings != null)
{
Console.WriteLine(settings.SiteName);
Console.WriteLine(settings.MaxItems);
}
設定値は存在しない場合や型変換に失敗する場合があるため、デフォルト値や検証処理も合わせて考えると安全です。
7-3. Console入力から値を取得する
コンソールアプリでユーザー入力を取得するには、Console.ReadLineを使います。
C#Console.Write("名前を入力してください: ");
string name = Console.ReadLine();
Console.WriteLine($"こんにちは、{name}さん");
Console.ReadLineの戻り値はstring?です。入力がnullになる可能性もあるため、必要に応じてnull対策を行います。
C#string name = Console.ReadLine() ?? "";
Console.WriteLine(name);
数値を入力させたい場合は、TryParseで変換します。
C#Console.Write("年齢を入力してください: ");
string input = Console.ReadLine();
if (int.TryParse(input, out int age))
{
Console.WriteLine($"年齢は{age}歳です");
}
else
{
Console.WriteLine("数値を入力してください");
}
ユーザー入力は想定外の値が入力される可能性が高いため、必ず検証してから利用することが重要です。
7-4. フォームやWebリクエストから値を取得する
ASP.NET Core MVCでは、フォームの入力値をアクションメソッドの引数やモデルとして取得できます。
C#[HttpPost]
public IActionResult Register(string name, int age)
{
Console.WriteLine(name);
Console.WriteLine(age);
return View();
}
複数の入力値を扱う場合は、ViewModelを使うと分かりやすくなります。
C#public class RegisterViewModel
{
public string Name { get; set; }
public int Age { get; set; }
}
C#[HttpPost]
public IActionResult Register(RegisterViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
string name = model.Name;
int age = model.Age;
return RedirectToAction("Complete");
}
Web APIでリクエストボディから値を取得する場合は、DTOを使うのが一般的です。
C#public class CreateUserRequest
{
public string Name { get; set; }
public int Age { get; set; }
}
C#[HttpPost]
public IActionResult Create([FromBody] CreateUserRequest request)
{
string name = request.Name;
int age = request.Age;
return Ok();
}
クエリ文字列から取得する場合は、[FromQuery]を使います。
C#[HttpGet]
public IActionResult Search([FromQuery] string keyword)
{
Console.WriteLine(keyword);
return Ok();
}
Webリクエストから値を取得する場合は、入力検証、必須チェック、文字数制限、不正な値の除外を忘れずに行いましょう。
7-5. 取得した値を安全に検証・変換する方法
ファイル、設定値、入力値など、外部から取得した値は信頼しすぎないことが大切です。取得した値は、利用する前に検証・変換しましょう。
文字列が空でないか確認するには、string.IsNullOrWhiteSpaceを使います。
C#string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("入力値が空です");
return;
}
数値に変換する場合は、TryParseを使います。
C#if (!int.TryParse(input, out int number))
{
Console.WriteLine("数値に変換できません");
return;
}
日付に変換する場合も同様です。
C#if (!DateTime.TryParse(input, out DateTime date))
{
Console.WriteLine("日付に変換できません");
return;
}
範囲チェックも重要です。
C#if (number < 0 || number > 100)
{
Console.WriteLine("0から100の範囲で入力してください");
return;
}
外部から取得した値は、「存在するか」「型が正しいか」「範囲内か」「業務ルールに合っているか」を確認してから使うことで、安全なプログラムになります。
8. C#で値を安全に取得するための実践テクニック
8-1. nullチェックとnull合体演算子の使い方
C#で値を安全に取得するには、nullチェックが欠かせません。基本的なnullチェックは次のように書きます。
C#if (user != null)
{
string name = user.Name;
}
より簡潔に書くなら、null条件演算子?.を使います。
C#string name = user?.Name;
nullの場合にデフォルト値を使いたい場合は、null合体演算子??を使います。
C#string name = user?.Name ?? "未設定";
メソッドの戻り値がnullの可能性がある場合にも使えます。
C#string title = GetTitle() ?? "タイトルなし";
nullチェックを適切に入れることで、NullReferenceExceptionを防ぎ、値を安全に取得できます。
8-2. TryParseで文字列を数値や日付に安全変換する
文字列から数値や日付を取得する場合は、ParseよりもTryParseを使うのが安全です。
C#string input = "123";
if (int.TryParse(input, out int number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("数値ではありません");
}
int.Parseは変換できない文字列を渡すとFormatExceptionを発生させます。
C#int number = int.Parse("abc"); // 例外
日付の場合も同じです。
C#string input = "2026-01-01";
if (DateTime.TryParse(input, out DateTime date))
{
Console.WriteLine(date);
}
else
{
Console.WriteLine("日付ではありません");
}
小数の場合はdecimal.TryParseやdouble.TryParseを使います。
C#if (decimal.TryParse("123.45", out decimal price))
{
Console.WriteLine(price);
}
ユーザー入力、CSV、設定ファイル、APIレスポンスなど、外部から取得した文字列を変換する場合は、基本的にTryParseを使うと安全です。
8-3. FirstOrDefault・SingleOrDefault使用時の注意点
LINQで値を取得するときによく使うのが、FirstOrDefaultやSingleOrDefaultです。
FirstOrDefaultは、条件に一致する最初の要素を取得します。存在しない場合は既定値を返します。
C#var users = new List<User>
{
new User { Name = "Alice", Age = 20 },
new User { Name = "Bob", Age = 30 }
};
User user = users.FirstOrDefault(u => u.Name == "Charlie");
if (user == null)
{
Console.WriteLine("見つかりません");
}
SingleOrDefaultは、条件に一致する要素が0件なら既定値、1件ならその値を返します。ただし、2件以上存在すると例外が発生します。
C#User user = users.SingleOrDefault(u => u.Name == "Alice");
「必ず1件だけ存在するべき」データを取得するならSingleOrDefaultが適しています。一方、「複数あるかもしれないが最初の1件でよい」場合はFirstOrDefaultを使います。
注意点は、値型の場合です。
C#var numbers = new List<int>();
int value = numbers.FirstOrDefault();
Console.WriteLine(value); // 0
intの既定値は0なので、「見つからなかった」のか「0が見つかった」のか区別できない場合があります。必要に応じてNullable型を使いましょう。
C#int? value = numbers
.Where(n => n > 100)
.Cast<int?>()
.FirstOrDefault();
8-4. 例外を起こしやすい取得処理と回避策
C#で値を取得するとき、次のような処理は例外を起こしやすいです。
C#string first = list[0];
string value = dictionary["key"];
string part = text.Substring(0, 10);
int number = int.Parse(input);
string name = user.Name;
それぞれ、次のように安全な書き方にできます。
Listや配列から取得する場合は、要素数を確認します。
C#if (list.Count > 0)
{
string first = list[0];
}
Dictionaryから取得する場合は、TryGetValueを使います。
C#if (dictionary.TryGetValue("key", out string value))
{
Console.WriteLine(value);
}
文字列の一部を取得する場合は、長さを確認します。
C#if (!string.IsNullOrEmpty(text) && text.Length >= 10)
{
string part = text.Substring(0, 10);
}
型変換にはTryParseを使います。
C#if (int.TryParse(input, out int number))
{
Console.WriteLine(number);
}
オブジェクトのプロパティ取得にはnull条件演算子を使います。
C#string name = user?.Name ?? "未設定";
取得処理は便利な反面、前提が崩れると例外につながります。値が存在することを確認してから取得する習慣をつけましょう。
8-5. 取得処理を読みやすく保守しやすく書くコツ
値を取得する処理は、短く書けるからといって詰め込みすぎると読みにくくなります。
たとえば、次のようなコードは一見短いですが、何をしているか分かりにくくなりがちです。
C#var value = users.FirstOrDefault(u => u.Id == id)?.Address?.City ?? "未設定";
短い処理であれば問題ありませんが、条件が複雑な場合は変数に分けると読みやすくなります。
C#var user = users.FirstOrDefault(u => u.Id == id);
if (user == null)
{
return "ユーザー未設定";
}
var address = user.Address;
if (address == null)
{
return "住所未設定";
}
return address.City ?? "市区町村未設定";
また、同じ取得処理を何度も書く場合は、メソッド化すると保守しやすくなります。
C#string GetDisplayName(User user)
{
return user?.Name ?? "未設定";
}
DBやJSONの取得処理では、変換処理を専用メソッドにまとめるとコードが整理されます。
C#int GetIntOrDefault(string value, int defaultValue = 0)
{
return int.TryParse(value, out int result)
? result
: defaultValue;
}
取得処理は「安全性」と「読みやすさ」のバランスが重要です。例外を避けるだけでなく、後から見ても意図が分かるコードを意識しましょう。
9. よくあるエラーと原因別の解決方法
9-1. IndexOutOfRangeExceptionが発生する原因と対処
IndexOutOfRangeExceptionは、配列や文字列で存在しないインデックスを指定したときに発生します。
C#int[] numbers = { 10, 20, 30 };
int value = numbers[3]; // 例外
配列のインデックスは0から始まるため、要素数が3の場合に指定できるインデックスは0、1、2です。3は範囲外です。
対処方法は、取得前に範囲を確認することです。
C#int index = 3;
if (index >= 0 && index < numbers.Length)
{
int value = numbers[index];
Console.WriteLine(value);
}
else
{
Console.WriteLine("インデックスが範囲外です");
}
文字列でも同様です。
C#string text = "ABC";
int index = 5;
if (index >= 0 && index < text.Length)
{
char c = text[index];
}
配列や文字列から値を取得するときは、インデックスの範囲確認を必ず行いましょう。
9-2. NullReferenceExceptionが発生する原因と対処
NullReferenceExceptionは、nullのオブジェクトからメンバーを取得しようとしたときに発生します。
C#User user = null;
string name = user.Name; // 例外
対処方法は、nullチェックを行うことです。
C#if (user != null)
{
string name = user.Name;
}
または、null条件演算子を使います。
C#string name = user?.Name;
デフォルト値を設定したい場合は、null合体演算子を組み合わせます。
C#string name = user?.Name ?? "未設定";
ネストしたオブジェクトの場合も同じです。
C#string city = user?.Address?.City ?? "住所未設定";
NullReferenceExceptionはC#で非常によく見かけるエラーです。オブジェクトがnullになる可能性がある箇所では、取得前に必ずnull対策を入れましょう。
9-3. KeyNotFoundExceptionが発生する原因と対処
KeyNotFoundExceptionは、Dictionaryに存在しないキーを指定して値を取得したときに発生します。
C#var map = new Dictionary<string, string>
{
{ "name", "Tanaka" }
};
string age = map["age"]; // 例外
対処方法として、ContainsKeyで確認する方法があります。
C#if (map.ContainsKey("age"))
{
string age = map["age"];
}
よりおすすめなのは、TryGetValueを使う方法です。
C#if (map.TryGetValue("age", out string age))
{
Console.WriteLine(age);
}
else
{
Console.WriteLine("ageキーは存在しません");
}
デフォルト値を使う場合は次のように書けます。
C#string age = map.TryGetValue("age", out string value)
? value
: "未設定";
Dictionaryから値を取得するときは、キーが必ず存在するとは限らない前提で実装しましょう。
9-4. InvalidCastException・FormatExceptionが発生する原因と対処
InvalidCastExceptionは、型変換が不正な場合に発生します。
C#object value = "123";
int number = (int)value; // 例外
この場合、valueの実体は文字列なので、直接intにキャストできません。文字列から数値に変換する必要があります。
C#object value = "123";
if (int.TryParse(value.ToString(), out int number))
{
Console.WriteLine(number);
}
FormatExceptionは、文字列の形式が変換先の型に合っていない場合に発生します。
C#int number = int.Parse("abc"); // 例外
対処方法は、TryParseを使うことです。
C#if (int.TryParse("abc", out int number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("数値に変換できません");
}
日付変換でも同様です。
C#if (DateTime.TryParse("2026-01-01", out DateTime date))
{
Console.WriteLine(date);
}
外部から取得した値は、想定した型や形式とは限りません。キャストやParseを使う前に、安全な変換方法を選びましょう。
9-5. JSON・DB取得時に値が取れない場合の確認ポイント
JSONやDBから値が取得できない場合は、まずキー名や列名が正しいか確認しましょう。
JSONでは、プロパティ名の大文字小文字が一致していないことがあります。
JSON{
"name": "Tanaka"
}
C#側でNameとして取得しようとしている場合、設定によっては値が入らないことがあります。JsonPropertyNameを使うと明示できます。
C#[JsonPropertyName("name")]
public string Name { get; set; }
JsonDocumentの場合は、TryGetPropertyでキーが存在するか確認します。
C#if (root.TryGetProperty("name", out JsonElement element))
{
string name = element.GetString();
}
DBの場合は、SQLの結果に対象列が含まれているか確認します。
SQLSELECT Id, Name FROM Users
C#側でEmail列を取得しようとしても、SQLでEmailを取得していなければエラーになります。
また、DBのNULLにも注意が必要です。
C#if (!reader.IsDBNull(reader.GetOrdinal("Email")))
{
string email = reader.GetString(reader.GetOrdinal("Email"));
}
JSONやDBから値が取れない場合は、次の点を確認すると原因を見つけやすくなります。
C#// 確認ポイント
// ・キー名や列名は正しいか
// ・大文字小文字は一致しているか
// ・値がnullまたはDBNullではないか
// ・型変換は正しいか
// ・対象データが本当に存在するか
// ・SQLやAPIレスポンスが想定どおりか
10. 目的別:C#で値を取得する方法の使い分け
10-1. 文字列の一部を取り出したい場合
文字列の一部を取り出したい場合は、目的に応じてSubstring、Range、Split、Regexを使い分けます。
固定位置から取得するならSubstringが分かりやすいです。
C#string code = "ABC-12345";
string prefix = code.Substring(0, 3);
Console.WriteLine(prefix); // ABC
C# 8.0以降で簡潔に書きたい場合はRangeを使えます。
C#string prefix = code[..3];
区切り文字で分割して取得するならSplitです。
C#string[] parts = code.Split('-');
if (parts.Length >= 2)
{
string left = parts[0];
string right = parts[1];
}
パターンに一致する値を取得したい場合はRegexが便利です。
C#Match match = Regex.Match(code, @"\d+");
if (match.Success)
{
string number = match.Value;
}
文字列取得では、位置が固定なのか、区切り文字があるのか、パターン検索が必要なのかで使う方法を選びましょう。
10-2. 配列やListから条件に合う値を取り出したい場合
配列やListから位置で値を取得する場合は、インデックスを使います。
C#var list = new List<string> { "A", "B", "C" };
string value = list[1]; // B
ただし、範囲外エラーを防ぐために、件数を確認します。
C#int index = 1;
if (index >= 0 && index < list.Count)
{
string value = list[index];
}
条件に合う最初の値を取得する場合はFirstOrDefaultを使います。
C#var user = users.FirstOrDefault(u => u.Id == 10);
if (user != null)
{
Console.WriteLine(user.Name);
}
複数件取得したい場合はWhereです。
C#var activeUsers = users.Where(u => u.IsActive).ToList();
Listから値を取得するときは、「1件だけ欲しいのか」「複数件欲しいのか」「存在しない場合をどう扱うのか」を考えてメソッドを選びましょう。
10-3. Dictionaryからキー指定で値を取り出したい場合
Dictionaryからキー指定で値を取得する場合、キーが必ず存在するならインデクサを使えます。
C#string value = dictionary["key"];
ただし、実務ではキーが存在しない可能性を考慮することが多いため、TryGetValueを使うのがおすすめです。
C#if (dictionary.TryGetValue("key", out string value))
{
Console.WriteLine(value);
}
else
{
Console.WriteLine("キーが存在しません");
}
デフォルト値を使う場合は、三項演算子と組み合わせます。
C#string value = dictionary.TryGetValue("key", out string result)
? result
: "デフォルト値";
設定値、キャッシュ、マスターデータなどをDictionaryで扱う場合は、キーの存在確認を忘れずに行いましょう。
10-4. JSONやAPIレスポンスから値を取り出したい場合
JSONやAPIレスポンスから一部の値だけを取得したい場合は、JsonDocumentが便利です。
C#using JsonDocument document = JsonDocument.Parse(json);
if (document.RootElement.TryGetProperty("name", out JsonElement nameElement))
{
string name = nameElement.GetString();
}
構造が決まっているJSONを扱う場合は、クラスに変換する方法がおすすめです。
C#User user = JsonSerializer.Deserialize<User>(json);
string name = user?.Name ?? "未設定";
APIレスポンスでは、キーが存在しない、値がnull、配列が空、型が想定と違うといったことが起こります。取得時には、TryGetProperty、nullチェック、型チェックを行いましょう。
C#if (root.TryGetProperty("items", out JsonElement items)
&& items.ValueKind == JsonValueKind.Array)
{
foreach (JsonElement item in items.EnumerateArray())
{
Console.WriteLine(item);
}
}
JSONから値を取得する場合は、簡単な処理ならJsonDocument、業務データとして扱うならJsonSerializerでクラス化、という使い分けが基本です。
10-5. データベースから単一値・複数行を取り出したい場合
データベースから単一の値を取得する場合は、ExecuteScalarが向いています。
C#string sql = "SELECT COUNT(*) FROM Users";
object result = command.ExecuteScalar();
int count = Convert.ToInt32(result);
複数行を取得する場合は、SqlDataReaderを使います。
C#using SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
string name = reader.GetString(reader.GetOrdinal("Name"));
Console.WriteLine(name);
}
Entity Frameworkを使っている場合は、LINQで取得できます。
C#var user = context.Users.FirstOrDefault(u => u.Id == id);
var users = context.Users
.Where(u => u.IsActive)
.ToList();
DBから値を取得するときは、取得件数によって方法を使い分けると分かりやすくなります。
C#// 単一値: ExecuteScalar
// 複数行: SqlDataReader
// オブジェクトとして扱う: Entity Framework
// 表形式で扱う: DataTable
また、DBのNULLはDBNull.Valueとして返ることがあるため、nullや型変換の対策も忘れずに行いましょう。
まとめ
C#で値を取得する方法は、対象によってさまざまです。変数やプロパティから値を取得する基本に加えて、文字列、配列、List、Dictionary、JSON、データベース、ファイル、設定値、ユーザー入力など、実際の開発では多くの場所から値を取り出します。
文字列から値を取得する場合は、Substring、Range、Split、IndexOf、Regexなどを使い分けます。配列やListから取得する場合は、インデックスの範囲外に注意し、条件検索にはLINQを活用します。Dictionaryでは、キーが存在しない場合に備えてTryGetValueを使うと安全です。
オブジェクトから値を取得する場合は、プロパティやgetアクセサを使います。nullの可能性がある場合は、null条件演算子?.やnull合体演算子??を使うことで、NullReferenceExceptionを防げます。
JSONから値を取得する場合は、JsonDocumentでキーを指定して取得する方法と、JsonSerializerでクラスに変換して取得する方法があります。APIレスポンスのように外部から取得するJSONでは、キーの存在確認やnullチェックが重要です。
データベースから値を取得する場合は、単一値ならExecuteScalar、複数行ならSqlDataReader、オブジェクトとして扱うならEntity Frameworkが便利です。DBのNULLはDBNull.Valueとして扱われることがあるため、型変換やnull処理に注意しましょう。
C#で値を安全に取得するための基本は、「存在確認」「nullチェック」「範囲チェック」「型変換チェック」です。値が必ず存在するという前提で書くのではなく、存在しない場合や変換できない場合を考慮して実装することで、例外に強く、保守しやすいコードになります。

