1

インベントリ プログラムでは、クラスItemItemCollection、および派生クラス を作成しましたComputer : Item

フォームで、 (一部のコンピューターを含む) という名前ItemCollectionの (の一般的なリスト) を作成し、各アイテムのプロパティ(場所、数量など)を表示したいと考えています。ItemTheseItemsThisItem

これを行っている間、コンピューターの個別のプロパティ (CPU、HDD、RAM など) も表示したいと考えています。私はこれまでのところこれを持っています:

foreach (Item ThisItem in TheseItems)
{
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading)

    if (ThisItem is Computer)
    {
        //Display distinct properties of Computer instance “ThisItem”
    }
}

これまでのところエラーはありませんが、続行する方法がわかりません。私がやりたいことをすることは可能ですか?

編集:ありがとう、ステーキ!キャスティングでは事前に割り当てられたプロパティにアクセスできないのではないかと心配していましたが (単に新しいプロパティを割り当てることができるだけです)、幸いなことに間違っていました! 私は今持っています:

Computer ThisComputer = ThisItem as Computer;
if (Computer != null)
{
     //Display distinct properties of Computer instance “ThisComputer”
}

私が受けた迅速な助けに本当に感銘を受けました. ありがとう!

4

4 に答える 4

1

これは私が通常使用するアプローチです。タイプをチェックしてからキャストするよりも少し速いかもしれません(これについての証拠はありません)。

foreach (Item ThisItem in TheseItems)
{
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading)

    var computer = ThisItem as Computer;
    if (computer != null)
    {
         //Display distinct properties of Computer instance “ThisItem”
    }
}
于 2013-06-27T20:20:29.190 に答える
1

あなたが持っているものはうまくいきます。

foreach (Item ThisItem in TheseItems)
{
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading)

    if (ThisItem is Computer)
    {
        Computer computerItem = (Computer)ThisItem;
        //Display distinct properties of Computer instance “ThisItem”
    }
}

または、asキーワードを使用してわずかな最適化を行います。

foreach (Item ThisItem in TheseItems)
{
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading)
    var computerItem = ThisItem as Computer;
    if (computerItem != null)
    {
        //Display distinct properties of Computer instance “ThisItem”
    }
}

また、私の友人は、これを支援するための優れたユーティリティ クラスを作成しました。とても参考になったので投稿しようと思います。

foreach (Item ThisItem in TheseItems)
{
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading)
    ThisItem.Match()
            .Case<Computer>(comp => /* Do stuff with your computer */)
            .Case<Television>(tv => /* Do stuff with your television */)
            .Default(item => /* Do stuff with your item */);
}

ユーティリティ クラスは次のようになります。以下に要点を示しますが、非常に拡張可能です。

public class Matcher<TMatch>
{
    private readonly TMatch _matchObj;
    private bool _isMatched;

    public Matcher(TMatch matchObj)
    {
        this._matchObj = matchObj;
    }

    public Matcher<TMatch> Case<TCase>(Action<TCase> action) where TCase : TMatch
    {
        if(this._matchObj is TCase)
        {
            this.DoCase(() => action((TCase)this._matchObj));
        }
        return this;
    }

    public void Default(Action<TMatch> action)
    {
        this.DoCase(() => action(this._matchObj));
    }

    private void DoCase(Action action)
    {
        if (!this._isMatched)
        {
            action();
            this._isMatched = true;
        }
    }
}

public static class MatcherExtensions
{
    public static Matcher<TMatch> Match<TMatch>(this TMatch matchObj)
    {
        return new Matcher<TMatch>(matchObj);
    }
}
于 2013-06-27T20:16:41.617 に答える
0

はい、IF 句内で派生クラスにキャストすると、プロパティが使用可能になります。

foreach (Item ThisItem in TheseItems)
{
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading)

    if (ThisItem is Computer)
    {
       var ThisComputer = (Computer) ThisItem;
       Display(ThisComputer.CPU);
       //etc
    }
}
于 2013-06-27T20:16:26.913 に答える