Start Debugging

.NET 10 で NIC のリストが爆発した? 自分を欺かずに GetAllNetworkInterfaces() をフィルターする

.NET 10 で Hyper-V、Docker、WSL、VPN の仮想アダプターがリストを埋め尽くしてしまうとき、GetAllNetworkInterfaces() をどうフィルターするか。トレードオフを明示した 2 段階フィルター付き。

.NET 8 から .NET 10 にアプリを移行した直後、NetworkInterface.GetAllNetworkInterfaces() が突然 10 個ではなく 80 個のアダプターを返すようになっても、それは気のせいではありません。これは 2026 年 1 月 7 日のスレッドで取り上げられた話題で、まさに「マイナー」な動作変更が breaking change のように感じられる、現実世界の痛みそのものです: Hyper-V、Docker、WSL、VPN、ループバック、その他のシステムアダプターからの仮想インターフェースが、「本物」の Ethernet や Wi-Fi デバイスを押しのけ始めます。

ソース: NetworkInterface.GetAllNetworkInterfaces breaking change (r/dotnet)

不都合な真実: 「物理」はヒューリスティックである

System.Net.NetworkInformation は、マシン、ドライバー、Windows の機能をまたいで信頼できる「これは物理 NIC です」という公式の単一のブール値を提供してくれません。最も安全な戦略は、自分の製品の要件にマッチするフィルターを構築することと、そのフィルターを監査可能かつテスト可能に保つことです。

「接続性に役立つ」と通常相関する厳しめのシグナルから始めます:

その後、第 2 段階として、より緩く環境固有な除外 (Docker、Hyper-V、WSL、VPN) を追加します。

トレードオフを明示した 2 段階のフィルター

スレッドではこのアプローチが提案されていました (可読性のために削減し、少しだけ強化しています):

using System.Net.NetworkInformation;

var candidates = NetworkInterface.GetAllNetworkInterfaces()
    .Where(nic => nic.OperationalStatus == OperationalStatus.Up)
    .Where(nic => nic.NetworkInterfaceType is
        NetworkInterfaceType.Ethernet or
        NetworkInterfaceType.Wireless80211 or
        NetworkInterfaceType.GigabitEthernet)
    .Where(nic => !LooksVirtual(nic))
    .ToArray();

static bool LooksVirtual(NetworkInterface nic)
{
    var desc = (nic.Description ?? "").ToLowerInvariant();
    var name = (nic.Name ?? "").ToLowerInvariant();

    string[] keywords =
    {
        "virtual", "hyper-v", "vmware", "virtualbox",
        "docker", "vpn", "tap-", "wsl", "pseudo"
    };

    return keywords.Any(k => desc.Contains(k) || name.Contains(k));
}

ハック的か? はい。しかし正直でもあります: ポリシーをコードに埋め込んでいることを認めているのです。

これをもう少し脆くないものにするには、文字列だけに頼らないでください:

好奇心ではなく、本番インシデントとしてデバッグする

.NET のバージョンによってアダプター数が変わるときは、観測可能な動作差として扱ってください:

.NET 10 はあなたに生のリストを渡してくれます。「本物」が何を意味するかは、依然としてあなたのアプリが決めなければなりません。

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< 戻る