C#/WinRT コンポーネント エラーの診断

この記事では、C#/WinRT で記述された Windows ランタイム コンポーネントでの制限に関する追加情報を説明します。 これは、作成者がコンポーネントをビルドするときに C#/WinRT から出されるエラー メッセージで提供される情報を拡張するものです。 既存の UWP .NET ネイティブ マネージド コンポーネントの場合、C# WinRT コンポーネントのメタデータは、.NET ツールである Winmdexp.exe を使用して生成されます。 Windows ランタイムのサポートが .NET から切り離されたため、コンポーネントから .winmd ファイルを生成するツールを C#/WinRT が提供します。 Windows ランタイムでは C# クラス ライブラリよりもコードに対する制約が多く、.winmd ファイルを生成する前に、C#/WinRT 診断スキャナー アラートによってそれらの制約が警告されます。

この記事では、ビルドにおいて C#/WinRT から報告されるエラーについて説明します。 この記事は、Winmdexp.exe ツールを使用する既存の UWP .NET ネイティブ マネージド コンポーネントの制限に関する情報の更新バージョンです。

この表を利用するには、エラー メッセージのテキストで検索するか (プレースホルダーの特定の値は省略してください)、メッセージ番号で検索してください。 必要な情報が見つからない場合は、この記事の最後にあるフィードバック ボタンをご利用いただくことができます。ドキュメントの内容を充実させるためにご協力をお願いします。 フィードバックには、エラー メッセージを含めてください。 また、C#/WinRT リポジトリで問題点をご連絡いただくこともできます。

この記事では、シナリオ別にエラー メッセージが整理されています。

有効な Windows ランタイム インターフェイスではないインターフェイスの実装

C#/WinRT コンポーネントは、非同期の処理や操作を表すユニバーサル Windows ランタイム インターフェイス (IAsyncActionIAsyncActionWithProgress<TProgress>IAsyncOperation<TResult>、または IAsyncOperationWithProgress<TResult, TProgress>) など、特定の Windows ランタイム インターフェイスを実装することはできません。 代わりに、Windows ランタイム コンポーネントに非同期操作を生成するための AsyncInfo クラスを使用してください。 注意: これらだけが無効なインターフェイスではありません。たとえば、クラスは System.Exception を実装できません。

エラー番号

メッセージ テキスト

CsWinRT1008

型 {0} の Windows ランタイム コンポーネントは、インターフェイス {1} を実装できません。このインターフェイスは有効な Windows ランタイム インターフェイスではありません

Windows ランタイムでは、オーバーロードされたメソッドは、オーバーロードの 1 つが既定のオーバーロードとして指定されている場合にのみ、同じ数のパラメーターを持つことができます。 属性 Windows.Foundation.Metadata.DefaultOverload を使用してください (CsWinRT1015、1016)。

配列を関数またはプロパティの入力または出力として使用する場合は、読み取り専用または書き込み専用のいずれかである必要があります (CsWinRT 1025)。 属性 System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray および System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray が用意されており、使用することができます。 この用意されている属性は、配列型のパラメーターでのみ使用し (CsWinRT1026)、パラメーターごとに 1 つのみ適用する必要があります (CsWinRT1023)。

out とマークされた配列パラメーターは、書き込み専用と想定されるため、属性を適用する必要はありません。 この場合、それを読み取り専用として修飾すると、エラー メッセージが表示されます (CsWinRT1024)。

属性 System.Runtime.InteropServices.InAttribute および System.Runtime.InteropServices.OutAttribute は、どの型のパラメーターにも使用しないでください (CsWinRT1021、1022)。

エラー番号

メッセージ テキスト

CsWinRT1015

クラス {2}: '{1}' の複数の {0} パラメーター オーバーロードが Windows.Foundation.Metadata.DefaultOverloadAttribute で修飾されています。 この属性は、メソッドの 1 つのオーバーロードにのみ適用できます。

CsWinRT1016

クラス {2}: {1} の {0} パラメーター オーバーロードには、属性 Windows.Foundation.Metadata.DefaultOverloadAttribute で修飾して既定のオーバーロードとして指定したメソッドが 1 つだけ必要です。

CsWinRT1021

メソッド '{0}' のパラメーター '{1}' は配列で、System.Runtime.InteropServices.InAttribute または System.Runtime.InteropServices.OutAttribute のいずれかが指定されています。 Windows ランタイムでは、配列パラメーターに ReadOnlyArray または WriteOnlyArray のいずれかを指定する必要があります。 必要に応じて、これらの属性を削除するか、適切な Windows ランタイム属性と置き換えてください。

CsWinRT1022

メソッド '{0}' に、System.Runtime.InteropServices.InAttribute または System.Runtime.InteropServices.OutAttribute が指定されたパラメーター '{1}' があります。Windows ランタイムでは、パラメーターを System.Runtime.InteropServices.InAttribute または System.Runtime.InteropServices.OutAttribute でマークすることはサポートされていません。 System.Runtime.InteropServices.InAttribute を削除して、代わりに、System.Runtime.InteropServices.OutAttribute を 'out' 修飾子に置き換えることを検討してください。

CsWinRT1023

メソッド '{0}' のパラメーター '{1}' は配列であり、ReadOnlyArray と WriteOnlyArray の両方が指定されています。 Windows ランタイムでは、配列パラメーターの内容は、読み取り可能または書き込み可能である必要があります。 属性の 1 つを '{1}' から削除してください。

CsWinRT1024

メソッド '{0}' には出力パラメーター '{1}' が指定されており、これは配列ですが、ReadOnlyArray 属性が指定されています。 Windows ランタイムでは、出力配列の内容は書き込み可能です。 '{1}' から属性を削除してください。

CsWinRT1025

メソッド '{0}' には、配列パラメーター '{1}' が指定されています。 Windows ランタイムでは、配列パラメーターの内容が読み取り可能または書き込み可能である必要があります。 ReadOnlyArray または WriteOnlyArray のいずれかを '{1}' に適用してください。

CsWinRT1026

メソッド '{0}' に指定されたパラメーター '{1}' は配列ではなく、ReadOnlyArray 属性または WriteOnlyArray 属性が指定されています。 Windows ランタイムでは、配列以外のパラメーターを ReadOnlyArray または WriteOnlyArray でマークすることはサポートされていません。

出力ファイルの名前空間エラーと無効な名前

Windows ランタイムでは、Windows メタデータ (.winmd) ファイル内のすべてのパブリック型は、.winmd ファイル名を共有する名前空間、またはそのファイル名のサブ名前空間の中にある必要があります。 たとえば、Visual Studio プロジェクトの名前が A.B (つまり、Windows ランタイム コンポーネントが A.B.winmd) の場合、パブリック クラス A.B.Class1 と A.B.C.Class2 を含めることができますが、A.Class3 または D.Class4 を含めることはできません。

注意

これらの制限はパブリック型だけに適用され、実装で使用されるプライベート型には適用されません。

A.Class3 の場合は、Class3 を別の名前空間に移動するか、Windows ランタイム コンポーネントの名前を A.winmd に変更することができます。 前の例では、A.B.winmd を呼び出すコードは A.Class3 を特定することはできません。

D.Class4 の場合は、ファイル名に D.Class4 と A.B 名前空間内のクラスの両方を含めることができないため、Windows ランタイム コンポーネントの名前を変更する方法では対処できません。 D.Class4 を別の名前空間に移動するか、別の Windows ランタイム コンポーネントに配置することができます。

ファイル システムでは大文字と小文字を区別できないため、大文字と小文字だけが異なる名前空間は許可されません (CsWinRT1002)。

エラー番号

メッセージ テキスト

CsWinRT1001

パブリック型の名前空間 ('{1}') が、他の名前空間 ('{0}') と共通のプレフィックスを共有していません。 Windows メタデータ ファイル内のすべての型は、ファイル名で指定される名前空間のサブ名前空間に存在する必要があります。

CsWinRT1002

'{0}' という名前の複数の名前空間が見つかりました。Windows ランタイムでは、大文字と小文字のみが異なる名前空間の名前を使用できません。

無効な Windows ランタイム型である型をエクスポートする

コンポーネントのパブリック インターフェイスは、Windows ランタイム型のみを公開する必要があります。 ただし、.NET には、.NET と Windows ランタイムで若干異なる、よく使用される多くの型のマッピングが用意されています。 これにより、.NET 開発者は、新しい型を習得する代わりに、使い慣れた型を使うことができます。 マップされた .NET Framework 型は、コンポーネントのパブリック インターフェイスで使用できます。 詳細については、Windows ランタイム コンポーネントでの型の宣言マネージド コードへの Windows ランタイム型の引き渡しWindows ランタイム型の .NET マッピングをご覧ください。

これらのマッピングの多くはインターフェイスです。 たとえば、IList<T> は、Windows ランタイム インターフェイス IVector<T> にマップされています。 パラメーター型として IList<string> の代わりに List<string> を使うと、C#/WinRT によって代替のリストが提供されます。このリストには、List<T> によって実装されたマップ済みのインターフェイスがすべて含まれています。 List<Dictionary<int, string>> など、入れ子になったジェネリック型を使用する場合、C#/WinRT では入れ子のレベルごとに選択肢が提供されます。 これらのリストはかなり長くなる場合があります。

一般に、最適なのは型に最も近いインターフェイスです。 たとえば、Dictionary<int、string>の場合、最適な選択肢は IDictionary<int、string> です。

エラー番号

メッセージ テキスト

CsWinRT1006

メンバー '{0}' の、シグネチャでの型は '{1}' です。 型 '{1}' は有効な Windows ランタイム型ではありません。 ただし、その型 (またはそのジェネリック パラメーター) は、有効な Windows ランタイム型のインターフェイスを実装しています。 メンバー シグネチャの型 '{1}' を、System.Collections.Generic の次のいずれかの型に変更することを検討してください: {2}。

Windows ランタイムでは、メンバー シグネチャ内の配列は 1 次元で、下限を 0 (ゼロ) に指定する必要があります。 myArray[][] (CsWinRT1017) や myArray[,] (CsWinRT1018) など、入れ子になった配列型は許可されていません。

注意

この制限は、実装で内部的に使用する配列には適用されません。

エラー番号

メッセージ テキスト

CsWinRT1017

メソッド '{0}' では、そのシグネチャに型 '{1}' の入れ子になった配列が指定されています。 Windows ランタイム メソッドのシグネチャ内の配列を入れ子にすることはできません。

CsWinRT1018

メソッド '{0}' では、そのシグネチャに型 '{1}' の多次元配列が指定されています。 Windows ランタイムのメソッド シグネチャの配列は 1 次元である必要があります。

使用できない型のフィールドを含む構造体

Windows ランタイムでは、構造体にはフィールドのみを含めることができ、フィールドは構造体にのみ含めることができます。 これらのフィールドはパブリックである必要があります。 有効なフィールド型には、列挙体、構造体、およびプリミティブ型が含まれます。

エラー番号

メッセージ テキスト

CsWinRT1007

構造体 {0} にパブリック フィールドが含まれていません。 Windows ランタイムの構造体には、少なくとも 1 つのパブリック フィールドが含まれている必要があります。

CsWinRT1011

構造体 {0} にパブリックでないフィールドが含まれています。 Windows ランタイムの構造体では、すべてのフィールドがパブリックである必要があります。

CsWinRT1012

構造体 {0} に const フィールドが含まれています。 定数は、Windows ランタイムの列挙型にのみ含めることができます。

CsWinRT1013

構造体 {0} には、型 {1} のフィールドが含まれています。{1} は Windows ランタイムの有効なフィールド型ではありません。 Windows ランタイムの構造体に含まれる各フィールドに指定できるのは、UInt8、Int16、UInt16、Int32、UInt32、Int64、UInt64、Single、Double、Boolean、String、Enum、または構造体自体のみです。

パラメーター名と生成されたコードとの競合

Windows ランタイムでは、戻り値は出力パラメーターであると見なされ、パラメーターの名前は一意である必要があります。 既定では、C#/WinRT は戻り値に __retval という名前を付けます。 メソッドに __retval という名前のパラメーターがあると、エラー CsWinRT1010 が発生します。 これを修正するには、パラメーターに __retvalue 以外の名前を指定してください。

エラー番号

メッセージ テキスト

CsWinRT1010

メソッド {0} のパラメーター名 {1} は、生成された C#/WinRT 相互運用機能で使用される戻り値パラメーター名と同じです。別のパラメーター名を使用してください。

その他

C#/WinRT で作成されるコンポーネントには、次に挙げるその他の制限があります。

  • オーバーロードされた演算子をパブリック型で公開することはできません。
  • クラスとインターフェイスをジェネリックにすることはできません。
  • クラスはシールする必要があります。
  • パラメーターを参照渡しにする (たとえば ref キーワードを使用する) ことはできません。
  • プロパティにはパブリックの get メソッドが必要です。
  • コンポーネントの名前空間には、少なくとも 1 つのパブリック型 (クラスまたはインターフェイス) が必要です。

エラー番号

メッセージ テキスト

CsWinRT1014

'{0}' は演算子オーバーロードです。 マネージド型は、Windows ランタイムで演算子のオーバーロードを公開できません。

CsWinRT1004

型 {0} はジェネリックです。 Windows ランタイム型をジェネリックにすることはできません。

CsWinRT1005

シールされていない型のエクスポートは、CsWinRT ではサポートされていません。 型 {0} を sealed としてマークしてください。

CsWinRT1020

メソッド '{0}' のパラメーター '{1}' が `ref` とマークされています。 参照パラメーターは、Windows ランタイムでは許可されていません。

CsWinRT1000

プロパティ '{0}' にパブリックのゲッター メソッドがありません。 Windows ランタイムでは、セッター専用プロパティはサポートされていません。

CsWinRT1003

Windows ランタイム コンポーネントには、少なくとも 1 つのパブリック型が必要です

Windows ランタイムでは、特定の数のパラメーターを持つコンストラクターをクラスに 1 つしか含めることができません。 たとえば、string 型の 1 つのパラメーターを持つコンストラクターと、int 型の 1 つのパラメーターを持つ別のコンストラクターの両方を含めることはできません。唯一の回避策は、コンストラクターごとに異なる数のパラメーターを使用することです。

エラー番号

メッセージ テキスト

CsWinRT1009

Windows ランタイムでは、同じアリティの複数のコンストラクターをクラスに含めることはできません。クラス {0} には {1} アリティの複数のコンストラクターがあります。