C# Optional Parameters(開発者向けの動作方法)
Defining Optional Parameters in C#
基本構文
オプション引数を定義するためには、メソッドの宣言内でデフォルト値を代入します。 このデフォルト値は定数式でなければなりません。 以下は、メソッド定義で1つ以上のオプションのデフォルト引数を定義する方法です。
public static void DisplayGreeting(string message, string end = "!")
{
Console.WriteLine(message + end);
}Public Shared Sub DisplayGreeting(ByVal message As String, Optional ByVal [end] As String = "!")
Console.WriteLine(message & [end])
End SubPublic Shared Sub DisplayGreeting(ByVal message As String, Optional ByVal [end] As String = "!")
Console.WriteLine(message & [end])
End Sub上記のコードスニペットでは、"end"はデフォルトパラメータ値が"!"のオプション引数です。 これにより、メソッドを2番目の引数を提供することなく呼び出すことができます。
オプション引数を使用したメソッド呼び出し
上記のメソッドを呼び出す方法は2通りあります。
static void Main()
{
DisplayGreeting("Hello"); // Outputs: Hello!
DisplayGreeting("Hello", "?"); // Outputs: Hello?
}static void Main()
{
DisplayGreeting("Hello"); // Outputs: Hello!
DisplayGreeting("Hello", "?"); // Outputs: Hello?
}Shared Sub Main()
DisplayGreeting("Hello") ' Outputs: Hello!
DisplayGreeting("Hello", "?") ' Outputs: Hello?
End SubShared Sub Main()
DisplayGreeting("Hello") ' Outputs: Hello!
DisplayGreeting("Hello", "?") ' Outputs: Hello?
End Sub最初の呼び出しでは、第2引数を省略し、デフォルト値を使用します。 2番目の呼び出しでは、特定の値を提供し、デフォルト値を上書きします。
名前付き引数とオプション引数の利用
C#の名前付き引数とオプション引数は、オプション引数を含むメソッド呼び出しの明確さを高めます。 これにより、呼び出し内で直接名前を指定することで、どの引数に値を与えるかを特定することができます。
名前付き引数を使用した例
// Named parameters
public static void ConfigureDevice(string deviceName, bool enableLogging = false, int timeout = 30)
{
Console.WriteLine($"Configuring {deviceName}: Logging={(enableLogging ? "On" : "Off")}, Timeout={timeout}s");
}// Named parameters
public static void ConfigureDevice(string deviceName, bool enableLogging = false, int timeout = 30)
{
Console.WriteLine($"Configuring {deviceName}: Logging={(enableLogging ? "On" : "Off")}, Timeout={timeout}s");
}' Named parameters
Public Shared Sub ConfigureDevice(ByVal deviceName As String, Optional ByVal enableLogging As Boolean = False, Optional ByVal timeout As Integer = 30)
Console.WriteLine($"Configuring {deviceName}: Logging={(If(enableLogging, "On", "Off"))}, Timeout={timeout}s")
End Sub' Named parameters
Public Shared Sub ConfigureDevice(ByVal deviceName As String, Optional ByVal enableLogging As Boolean = False, Optional ByVal timeout As Integer = 30)
Console.WriteLine($"Configuring {deviceName}: Logging={(If(enableLogging, "On", "Off"))}, Timeout={timeout}s")
End Sub名前付き引数を使用して、順序を無視して値を指定したり、オプション引数を飛ばすことができます。
static void Main()
{
ConfigureDevice("Router", timeout: 60);
}static void Main()
{
ConfigureDevice("Router", timeout: 60);
}Shared Sub Main()
ConfigureDevice("Router", timeout:= 60)
End SubShared Sub Main()
ConfigureDevice("Router", timeout:= 60)
End Subこの呼び出しでは、デフォルトのenableLoggingを使用しつつ、タイムアウトの値を指定するオプション引数を使用しています。
固定引数とオプション引数の組み合わせ
メソッドには必須引数(固定引数)とオプション引数の両方を含めることができます。 必須引数は、以下のコードスニペットに示されるように、メソッド宣言において常にオプションより前に来なければなりません。
コード例
public static void CreateProfile(string firstName, string lastName, int age = 25, string city = "Unknown")
{
Console.WriteLine($"Name: {firstName} {lastName}, Age: {age}, City: {city}");
}public static void CreateProfile(string firstName, string lastName, int age = 25, string city = "Unknown")
{
Console.WriteLine($"Name: {firstName} {lastName}, Age: {age}, City: {city}");
}Public Shared Sub CreateProfile(ByVal firstName As String, ByVal lastName As String, Optional ByVal age As Integer = 25, Optional ByVal city As String = "Unknown")
Console.WriteLine($"Name: {firstName} {lastName}, Age: {age}, City: {city}")
End SubPublic Shared Sub CreateProfile(ByVal firstName As String, ByVal lastName As String, Optional ByVal age As Integer = 25, Optional ByVal city As String = "Unknown")
Console.WriteLine($"Name: {firstName} {lastName}, Age: {age}, City: {city}")
End Subメソッドの呼び出し
static void Main()
{
CreateProfile("John", "Doe"); // Uses default age and city
CreateProfile("Jane", "Doe", 30, "New York"); // Specifies all parameters
}static void Main()
{
CreateProfile("John", "Doe"); // Uses default age and city
CreateProfile("Jane", "Doe", 30, "New York"); // Specifies all parameters
}Shared Sub Main()
CreateProfile("John", "Doe") ' Uses default age and city
CreateProfile("Jane", "Doe", 30, "New York") ' Specifies all parameters
End SubShared Sub Main()
CreateProfile("John", "Doe") ' Uses default age and city
CreateProfile("Jane", "Doe", 30, "New York") ' Specifies all parameters
End Sub引数を省略する柔軟性により、同じメソッドを異なる文脈で使用することができ、複数のオーバーロードを必要としません。
デフォルト値は定数式でなければなりません
オプション引数のデフォルトパラメータは定数式でなければならず、コンパイル時に評価される必要があります。これにより、デフォルト値が常に安定かつ予測可能であることが保証されます。
デフォルト値の正しい使用
public static void SendEmail(string address, string subject = "No Subject", string body = "")
{
Console.WriteLine($"Sending email to {address}\nSubject: {subject}\nBody: {body}");
}public static void SendEmail(string address, string subject = "No Subject", string body = "")
{
Console.WriteLine($"Sending email to {address}\nSubject: {subject}\nBody: {body}");
}Imports Microsoft.VisualBasic
Public Shared Sub SendEmail(ByVal address As String, Optional ByVal subject As String = "No Subject", Optional ByVal body As String = "")
Console.WriteLine($"Sending email to {address}" & vbLf & "Subject: {subject}" & vbLf & "Body: {body}")
End SubImports Microsoft.VisualBasic
Public Shared Sub SendEmail(ByVal address As String, Optional ByVal subject As String = "No Subject", Optional ByVal body As String = "")
Console.WriteLine($"Sending email to {address}" & vbLf & "Subject: {subject}" & vbLf & "Body: {body}")
End Subオーバーロード対オプション引数
メソッドのオーバーロードは、異なるユースケースに対して複数のメソッドシグネチャを作成することを伴いますが、オプション引数を使用することで、単一のメソッドで多様なシナリオを処理できます。
コードによる比較
オーバーロードされたメソッドは次のようになります:
// Method overloading
public static void Alert(string message)
{
Console.WriteLine(message);
}
public static void Alert(string message, bool urgent)
{
if (urgent)
Console.WriteLine("Urgent: " + message);
else
Console.WriteLine(message);
}// Method overloading
public static void Alert(string message)
{
Console.WriteLine(message);
}
public static void Alert(string message, bool urgent)
{
if (urgent)
Console.WriteLine("Urgent: " + message);
else
Console.WriteLine(message);
}' Method overloading
Public Shared Sub Alert(ByVal message As String)
Console.WriteLine(message)
End Sub
Public Shared Sub Alert(ByVal message As String, ByVal urgent As Boolean)
If urgent Then
Console.WriteLine("Urgent: " & message)
Else
Console.WriteLine(message)
End If
End Sub' Method overloading
Public Shared Sub Alert(ByVal message As String)
Console.WriteLine(message)
End Sub
Public Shared Sub Alert(ByVal message As String, ByVal urgent As Boolean)
If urgent Then
Console.WriteLine("Urgent: " & message)
Else
Console.WriteLine(message)
End If
End Subオプション引数を使用した等価なメソッド:
public static void Alert(string message, bool urgent = false)
{
if (urgent)
Console.WriteLine("Urgent: " + message);
else
Console.WriteLine(message);
}public static void Alert(string message, bool urgent = false)
{
if (urgent)
Console.WriteLine("Urgent: " + message);
else
Console.WriteLine(message);
}Public Shared Sub Alert(ByVal message As String, Optional ByVal urgent As Boolean = False)
If urgent Then
Console.WriteLine("Urgent: " & message)
Else
Console.WriteLine(message)
End If
End SubPublic Shared Sub Alert(ByVal message As String, Optional ByVal urgent As Boolean = False)
If urgent Then
Console.WriteLine("Urgent: " & message)
Else
Console.WriteLine(message)
End If
End Sub
オプション引数を使用する利点
オプション引数は、メソッドインターフェイスを簡素化し、多数のオーバーロードの必要性を減らします。 メソッドをより柔軟にし、コードベースを保守しやすく、理解しやすくします。
オプション引数の課題
オプション引数を使いすぎると、各メソッドが正しく実行するために求めるものについて混乱を招く可能性があります。 特に多くの引数がある場合や、デフォルト値が明白でない場合、メソッドの意図を不明瞭にする可能性があります。
ベストプラクティス
1.オプション パラメータを制限する:メソッド シグネチャが過度に複雑にならないように、オプション パラメータを慎重に使用します。 2.名前付き引数を使用する:特に特定のオプション パラメータをスキップする場合に、メソッド呼び出しの明確さが向上します。 3.デフォルト値を文書化する:誤用や混乱を防ぐために、各パラメータの機能とデフォルト値の意味を文書化します。
IronPDFをC#の任意パラメータと共に利用する

IronPDFは、開発者がアプリケーション内でPDF文書を作成、操作、およびレンダリングすることを可能にする便利な .NET ライブラリです。 HTMLを効率的にPDFに変換します。 このHTMLは、HTML文字列、HTMLファイル、URLなど、さまざまな形式で可能です。 請求書、レポート、またはカスタマイズされたユーザーコンテンツなど、動的なPDF文書の生成を必要とするアプリケーションに最適です。 IronPDFを使用すると、開発者は .NET Framework を完全に活用して効率的にPDFファイルを処理できます。
IronPDFの際立った機能は、HTMLを簡単にPDFに変換し、レイアウトやスタイルを保持することです。 これは、レポート、請求書、またはドキュメントといったWebベースのコンテンツからPDFを生成するのに最適です。 HTMLファイル、URL、HTML文字列をPDFファイルに変換できます。
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
// 1. Convert HTML String to PDF
var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");
// 2. Convert HTML File to PDF
var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");
// 3. Convert URL to PDF
var url = "http://ironpdf.com"; // Specify the URL
var pdfFromUrl = renderer.RenderUrlAsPdf(url);
pdfFromUrl.SaveAs("URLToPDF.pdf");
}
}using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
// 1. Convert HTML String to PDF
var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");
// 2. Convert HTML File to PDF
var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");
// 3. Convert URL to PDF
var url = "http://ironpdf.com"; // Specify the URL
var pdfFromUrl = renderer.RenderUrlAsPdf(url);
pdfFromUrl.SaveAs("URLToPDF.pdf");
}
}Imports IronPdf
Module Program
Sub Main(args As String())
Dim renderer = New ChromePdfRenderer()
' 1. Convert HTML String to PDF
Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")
' 2. Convert HTML File to PDF
Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")
' 3. Convert URL to PDF
Dim url = "http://ironpdf.com" ' Specify the URL
Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
pdfFromUrl.SaveAs("URLToPDF.pdf")
End Sub
End ModuleImports IronPdf
Module Program
Sub Main(args As String())
Dim renderer = New ChromePdfRenderer()
' 1. Convert HTML String to PDF
Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")
' 2. Convert HTML File to PDF
Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")
' 3. Convert URL to PDF
Dim url = "http://ironpdf.com" ' Specify the URL
Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
pdfFromUrl.SaveAs("URLToPDF.pdf")
End Sub
End ModuleIronPDFとC#のオプション引数を組み合わせることで、PDF文書生成のプロセスを簡単にすることができます。 オプションのパラメーターを利用することで、開発者はPDF生成のための柔軟なメソッドを作成し、異なる入力と要件に適応できるようにし、メソッドのオーバーロードを最小限に抑えることができます。
コード例
こちらは、IronPDFとC#のオプション引数を使用して、単純なHTMLテンプレートからカスタマイズされたPDFレポートを生成し、詳細(タイトルや特定のレポートセクションを含めるかどうかなど)を調整する例です。
using IronPdf;
using System;
public class PdfReportGenerator
{
// Method to generate PDF with optional parameters
public static void CreatePdfReport(string htmlContent, string filePath = "Report.pdf", bool includeCharts = true, string reportTitle = "Monthly Report")
{
// Optional parameters allow customization of the report's title and content dynamically
var renderer = new ChromePdfRenderer();
// Customize the PDF document
renderer.RenderingOptions.TextHeader.CenterText = reportTitle;
renderer.RenderingOptions.TextFooter.CenterText = "Generated on " + DateTime.Now.ToString("dd-MM-yyyy");
renderer.RenderingOptions.MarginTop = 50; // Set the top margin
renderer.RenderingOptions.MarginBottom = 50; // Set the bottom margin
if (!includeCharts)
{
// Modify HTML content to remove chart sections if not included
htmlContent = htmlContent.Replace("<div class='charts'></div>", "");
}
// Render the HTML to PDF
PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
// Save the generated PDF to a file
pdf.SaveAs(filePath);
Console.WriteLine($"PDF report has been created at {filePath}");
}
static void Main()
{
License.LicenseKey = "License-Key"; // Specify the license key if required
string htmlTemplate = @"
<html>
<head>
<title>Monthly Report</title>
</head>
<body>
<h1>Monthly Performance Report</h1>
<p>This section contains text describing the overall performance for the month.</p>
<div class='charts'>
<h2>Sales Charts</h2>
<!-- Placeholder for charts -->
</div>
</body>
</html>";
// Call the CreatePdfReport method with different parameters
CreatePdfReport(htmlTemplate, "BasicReport.pdf", false, "Basic Monthly Report");
CreatePdfReport(htmlTemplate, "FullReport.pdf", true, "Detailed Monthly Report");
}
}using IronPdf;
using System;
public class PdfReportGenerator
{
// Method to generate PDF with optional parameters
public static void CreatePdfReport(string htmlContent, string filePath = "Report.pdf", bool includeCharts = true, string reportTitle = "Monthly Report")
{
// Optional parameters allow customization of the report's title and content dynamically
var renderer = new ChromePdfRenderer();
// Customize the PDF document
renderer.RenderingOptions.TextHeader.CenterText = reportTitle;
renderer.RenderingOptions.TextFooter.CenterText = "Generated on " + DateTime.Now.ToString("dd-MM-yyyy");
renderer.RenderingOptions.MarginTop = 50; // Set the top margin
renderer.RenderingOptions.MarginBottom = 50; // Set the bottom margin
if (!includeCharts)
{
// Modify HTML content to remove chart sections if not included
htmlContent = htmlContent.Replace("<div class='charts'></div>", "");
}
// Render the HTML to PDF
PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
// Save the generated PDF to a file
pdf.SaveAs(filePath);
Console.WriteLine($"PDF report has been created at {filePath}");
}
static void Main()
{
License.LicenseKey = "License-Key"; // Specify the license key if required
string htmlTemplate = @"
<html>
<head>
<title>Monthly Report</title>
</head>
<body>
<h1>Monthly Performance Report</h1>
<p>This section contains text describing the overall performance for the month.</p>
<div class='charts'>
<h2>Sales Charts</h2>
<!-- Placeholder for charts -->
</div>
</body>
</html>";
// Call the CreatePdfReport method with different parameters
CreatePdfReport(htmlTemplate, "BasicReport.pdf", false, "Basic Monthly Report");
CreatePdfReport(htmlTemplate, "FullReport.pdf", true, "Detailed Monthly Report");
}
}Imports IronPdf
Imports System
Public Class PdfReportGenerator
' Method to generate PDF with optional parameters
Public Shared Sub CreatePdfReport(ByVal htmlContent As String, Optional ByVal filePath As String = "Report.pdf", Optional ByVal includeCharts As Boolean = True, Optional ByVal reportTitle As String = "Monthly Report")
' Optional parameters allow customization of the report's title and content dynamically
Dim renderer = New ChromePdfRenderer()
' Customize the PDF document
renderer.RenderingOptions.TextHeader.CenterText = reportTitle
renderer.RenderingOptions.TextFooter.CenterText = "Generated on " & DateTime.Now.ToString("dd-MM-yyyy")
renderer.RenderingOptions.MarginTop = 50 ' Set the top margin
renderer.RenderingOptions.MarginBottom = 50 ' Set the bottom margin
If Not includeCharts Then
' Modify HTML content to remove chart sections if not included
htmlContent = htmlContent.Replace("<div class='charts'></div>", "")
End If
' Render the HTML to PDF
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(htmlContent)
' Save the generated PDF to a file
pdf.SaveAs(filePath)
Console.WriteLine($"PDF report has been created at {filePath}")
End Sub
Shared Sub Main()
License.LicenseKey = "License-Key" ' Specify the license key if required
Dim htmlTemplate As String = "
<html>
<head>
<title>Monthly Report</title>
</head>
<body>
<h1>Monthly Performance Report</h1>
<p>This section contains text describing the overall performance for the month.</p>
<div class='charts'>
<h2>Sales Charts</h2>
<!-- Placeholder for charts -->
</div>
</body>
</html>"
' Call the CreatePdfReport method with different parameters
CreatePdfReport(htmlTemplate, "BasicReport.pdf", False, "Basic Monthly Report")
CreatePdfReport(htmlTemplate, "FullReport.pdf", True, "Detailed Monthly Report")
End Sub
End ClassImports IronPdf
Imports System
Public Class PdfReportGenerator
' Method to generate PDF with optional parameters
Public Shared Sub CreatePdfReport(ByVal htmlContent As String, Optional ByVal filePath As String = "Report.pdf", Optional ByVal includeCharts As Boolean = True, Optional ByVal reportTitle As String = "Monthly Report")
' Optional parameters allow customization of the report's title and content dynamically
Dim renderer = New ChromePdfRenderer()
' Customize the PDF document
renderer.RenderingOptions.TextHeader.CenterText = reportTitle
renderer.RenderingOptions.TextFooter.CenterText = "Generated on " & DateTime.Now.ToString("dd-MM-yyyy")
renderer.RenderingOptions.MarginTop = 50 ' Set the top margin
renderer.RenderingOptions.MarginBottom = 50 ' Set the bottom margin
If Not includeCharts Then
' Modify HTML content to remove chart sections if not included
htmlContent = htmlContent.Replace("<div class='charts'></div>", "")
End If
' Render the HTML to PDF
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(htmlContent)
' Save the generated PDF to a file
pdf.SaveAs(filePath)
Console.WriteLine($"PDF report has been created at {filePath}")
End Sub
Shared Sub Main()
License.LicenseKey = "License-Key" ' Specify the license key if required
Dim htmlTemplate As String = "
<html>
<head>
<title>Monthly Report</title>
</head>
<body>
<h1>Monthly Performance Report</h1>
<p>This section contains text describing the overall performance for the month.</p>
<div class='charts'>
<h2>Sales Charts</h2>
<!-- Placeholder for charts -->
</div>
</body>
</html>"
' Call the CreatePdfReport method with different parameters
CreatePdfReport(htmlTemplate, "BasicReport.pdf", False, "Basic Monthly Report")
CreatePdfReport(htmlTemplate, "FullReport.pdf", True, "Detailed Monthly Report")
End Sub
End ClassこちらがFullReport PDFファイルのプレビューです:

コード例におけるCreatePdfReportメソッドは、HTMLコンテンツからPDF文書を生成するよう構築されており、ファイルパス、チャートの含有、レポートタイトルなどのオプション引数での柔軟性を提供します。 この設計により、メソッドは最小限のコード調整で異なるレポートニーズに適応することができます。 メソッド内では、IronPDFの設定を調整して、PDFにレポートタイトルと生成された日付を表示するカスタムヘッダーおよびフッターを含めています。
また、文書のビジュアルレイアウトを改善するために余白も調整されます。 Depending on whether the includeCharts parameter is true or false, the HTML content is dynamically modified to either include or exclude chart visuals. 最終的に、潜在的に修正されたHTMLがPDFに変換され、指定された場所に保存されます。 この例は、オプション引数がカスタマイズされたPDFレポートの作成プロセスを大きく簡素化する方法を示しています。
結論
結論として、オプション引数を使用すると、開発者は複数のオーバーロードされたメソッドの必要性を減らし、より柔軟で保守しやすいコードを作成できます。 C#のオプション引数とIronPDFライブラリを組み合わせることで、開発者はカスタマイズされたPDF文書を効率的に生成できます。 この統合は、コードベースを簡素化するだけでなく、機能性を高め、異なるレポート要件やユーザーの好みに適応しやすくします。
IronPDF自体は、PDF機能をアプリケーションに組み込みたい.NET開発者にとって強力なツールであり、その機能をテストしたい人には無料のIronPDFトライアルを提供しています。 継続的な使用のために、$999から始まるライセンスは、プロフェッショナルグレードのPDF操作に対する費用対効果の高いソリューションを提供します。
ジェイコブ・メラーはIron Softwareの最高技術責任者(CTO)であり、C# PDFテクノロジーを開拓する先見的なエンジニアです。Iron Softwareのコアコードベースを支えるオリジナル開発者として、彼は創業以来、会社の製品アーキテクチャを形成し、CEOのCameron Rimingtonとともに、会社をNASA、Tesla、および世界的な政府機関にサービスを提供する50人以上の会社に変えました。1999年にロンドンで最初のソフトウェアビジネスを開業し、2005年に最初 for .NETコンポーネントを作成した後、Microsoftのエコシステム全体で複雑な問題を解決することを専門としました。