4

以下に示すように、結果をインターフェイスにキャストする Linq (to Objects) クエリを作成しようとしています。

    var data = (from row in CicApplication.Vaporizer473Cache
                where row.Coater == coater
                select row).Cast<IVaporizerData>();

選択でインターフェイスのインスタンスを作成できないため、これが唯一の方法のようです。2 つの質問があります。

  1. キャストは実際にどのように行われますか?ソース内の各プロパティを見つけて、その値を同じ名前のインターフェイス プロパティにコピーしますか?

  2. ソースに含まれていないインターフェイスにプロパティがありますが、この操作中に何らかの方法でその値を設定したいと考えています。これは可能ですか?または、クエリの後に for each ステートメントで行う必要がありますか?

それが役立つ場合、データのソース (Vaporizer473Cache) のクラス定義は次のようになります。インターフェイスは非常に似ています。

internal class Vaporizer473
{
    /// <summary>
    /// Gets or sets the Coater property
    /// </summary>
    public string Coater { get; set; }

    /// <summary>
    /// Gets or sets the CoaterTime property
    /// </summary>
    public DateTime? CoaterTime { get; set; }

    /// <summary>
    /// Gets or sets the TemperatureLeftTubeA property
    /// </summary>
    public double? TemperatureLeftTubeA { get; set; }

    /// <summary>
    /// Gets or sets the TemperatureLeftTubeB property
    /// </summary>
    public double? TemperatureLeftTubeB { get; set; }

    /// <summary>
    /// Gets or sets the TemperatureRightTubeA property
    /// </summary>
    public double? TemperatureRightTubeA { get; set; }

    /// <summary>
    /// Gets or sets the TemperatureRightTubeB property
    /// </summary>
    public double? TemperatureRightTubeB { get; set; }

}

4

3 に答える 3

5

コンパイラは、提供された構文に文句を言うことはありませんが、実行されません。実装されていないインターフェイスにオブジェクトをキャストすることはできません。

IEnumerableCast メソッドは、指定されたオブジェクトの各オブジェクトを、指​​定したジェネリック型にキャストしようとする単なる便利なメソッドです。Vaporizer473を実装した場合IVaporizerData、次のように簡単に言うことができます。

var data = from row in CicApplication.Vaporizer473Cache
           where row.Coater == coater
           select (IVaporizerData)row;

第二に:

ソースに含まれていないインターフェイスにプロパティがありますが、この操作中に何らかの方法でその値を設定したいと考えています。これは可能ですか?または、クエリの後に for each ステートメントで行う必要がありますか?

ここまででわかったように、クラスはインターフェイスにプロパティを実装する必要があります。(実際のクラスの実装などでインテリセンスが混雑しないように、これを明示的に行うことができます。)複雑なデリゲートを使用して値を設定することは可能Selectですが、LINQ が作成された目的ではありません。それを思いとどまらせます。これは、forループが適切なケースです。

キャッシュから取得したアイテムを変更する場合、それらのクローンではなく元のオブジェクトを変更することになることに注意してください。これは広範囲に影響を与える可能性があります。代わりに、探しているデータを表す新しいオブジェクトを作成したい場合があります。

于 2012-12-11T19:32:32.117 に答える
1
  1. とてもシンプルです。オブジェクトを別の型にキャストしても、別のオブジェクトが作成されるわけではありません。これは、同じオブジェクトの異なる「ビュー」です。それを行うには、クラスでインターフェイスを実装する必要があります。したがって、キャストは、同じオブジェクトがまだ列挙可能であることを意味します。

  2. オブジェクトをキャストするときに新しいオブジェクトを作成しないため、インターフェイスの extra プロパティの値を設定できません。ただし、オブジェクトがインターフェイスを実装しているため、オブジェクトに既にプロパティがあることも意味します。

于 2012-12-11T19:35:07.213 に答える
1

あなたの最初の質問に答えるために、はい、これはそれがどのように行われるかです. ただし、コードを見ると、Vaporizer473クラスが実装していないようIVaporizorDataです。それが単なる見落としだったと仮定しますか?Cast<>()そうでない場合は、呼び出しを機能させるためにそのインターフェイスを実装する必要があります。

2 番目の質問については、はい、後で for-each ブロックに設定するか、 a を使用しSelectてプロパティの設定とキャストの両方を行うことができます。

CicApplication.Vaporizer473Cache
.Where( r => r.Coater = coater)
.Select((r) => {
   r.SomeProperty = somevalue;
   return r as IVaporizerData
});
于 2012-12-11T19:35:25.343 に答える