3

これは私の知識の欠如/悪いプログラミングの練習を示しているだけかもしれませんが、次のことを知りたいです:a)これはすでに存在しますb)存在しない場合、それが悪いプログラミングの練習である場合

しかし、ここに私の質問があります:

クラスがあり、それを「コンピューター」と呼び、会社内のすべてのコンピューターのデータを保持しているとします。さて、たまたまこの会社には数千台のDellコンピュータと数千台のHPがあり、他には何もありません。(ここでも私に固執してください、これは私のポイントを説明するための単なる例です)

これで、クラスを次のように定義できます。

Public Class Computer

Dim Type as string
Dim SerialNumber as string
Dim User as String
...

End Class

ここで、私のコードで2つのリストを作成します。

Dim DellComps as new list(of computer)
Dim HPComps as new list(of computer)

明らかに、のためにDellComps、彼らはすべて持っているでしょう.Type = "Dell"、そして、のためにHPComps、すべてが持っているでしょう.Type = "HP"

これで、コンストラクターでこの変数を非常に簡単に設定できることがわかりましたが、クラス内で変数を宣言するためのよりスマートな方法があるかどうか疑問に思っています-クラスのすべてのインスタンスが存在するVB Shared / C#静的ステートメントと同様です同じ変数を共有します。

私の考えは次のとおりです。

  1. クラスを継承し、子クラスに共有変数を作成します
  2. そのままにして、コンストラクターでTypevarを宣言します。
  3. 多分これはどういうわけかインターフェースを介して行うことができるものです
  4. 最も可能性が高い-私が知らないこと

ありがとう、そして私が求めていることが理にかなっていることを願っています!!!

4

3 に答える 3

5

最も近いのは、abstractキーワードを使用することです。抽象クラスがあり、具象サブクラスによってComputerオーバーライドされます。大まかな (C#) 例は次のようになります。DellComputerHpComputer

public abstract class Computer
{
    public string Type { get; protected set; }
}

public class DellComputer : Computer 
{
    public DellComputer()
    {
       this.Type = "Dell"
    }
}

通常、多数のインスタンス間で単一の変数を共有することは望ましくありません。これは、カプセル化が壊れ、より現実的には、コードを単体テストしようとすると大きな問題になる可能性があるためです。したがって、あなたが話していることの純粋な形はあまり良い考えではありませんが、現実的なユースケースはかなり一般的であり、間違いなくサポートされています.

編集: 以下のコメントの一部として、非常に密接に関連する仮想キーワードを使用する別のアプローチを次に示します!

public abstract class Computer
{
    public virtual string Type { get; }
}

public class DellComputer : Computer 
{
    public override string Type 
    {
        get {
           return "Dell";
        }
    }
}
于 2012-10-26T19:05:10.997 に答える
2

コンピューターのタイプを示すフラグをコンストラクターに常に設定している場合(これは、タイプを編集できる一般的なビジネス・オブジェクトのシナリオではありません)、サブクラスを使用して問題を実際に解決できる可能性があります。

コンピュータをサブクラス化して、DellComputerクラスとHpComputerクラスを作成します。

各タイプのコンピューターのリストを作成する場合、1つの方法は、すべてのコンピューターのマスターリストを作成し、LinqのEnumerable.OfType(TResult)を使用して、目的のタイプに一致するインスタンスを選択することです。

クラスの作成後にクラスのタイプを編集可能にする場合は、代わりに、コンピューターのタイプを変更するためのプロパティを指定してください。便宜上、プロパティを設定するコンストラクターのオーバーロードを提供することもできます(個人的にはそれを避けますが)。その場合は、コンストラクターのオーバーロードでプロパティを使用してタイプを設定します。

アップデート

ファクトリパターンがどのように見えるかの例。

public abstract class Computer
{
    public virtual string Type { get; }
}

public class DellComputer : Computer 
{
    public override string Type 
    {
        get { return "Dell"; }
    }
}

public class HpComputer : Computer 
{
    public override string Type 
    {
        get { return "HP"; }
    }
}

// Here I'm using an enum to indicate the type desired.  You might use a string
// or anything else that makes sense in your problem domain.

public enum ComputerType
{
    Dell = 1,
    Hp = 2
}

public class ComputerFactory
{
    public Computer Create(ComputerType type)
    {
        switch (type)
        {
            case ComputerType.Dell:
                return new DellComputer();
            case ComputerType.Hp:
                return new HpComputer();
            default:
                throw new InvalidArgumentException();
        }
    }
}

// Usage would be something like:


List<Computer> computers = new List<Computer>();
computers.Add(ComputerFactory.Create(ComputerTypes.Dell);
computers.Add(ComputerFactory.Create(ComputerTypes.Dell);
computers.Add(ComputerFactory.Create(ComputerTypes.Hp);
于 2012-10-26T18:58:41.130 に答える
0

コレクションやその他のデータを持つクラスを作成できます。この場合、PCには型がありません。

public class Computers 
{
     private List<Computer> pcs= new List<computer>();

     public List<Computer> PCs get { return { pcs; } };

     public String Brand { get; private set; }

     public Computers(string brand) {Brand = brand;}
}

静的変数について。クラスのすべてのメンバーがブランドを共有することは望ましくありません。

上記の場合、コンストラクターでデータを繰り返します。
デルがHPと同じプロパティを持っている場合、私は同じクラスを使用します。
新しいブランドを購入すると言った場合、本当に新しいクラスまたはサブクラスを作成しますか?
ブランドの構造化されたリストが必要な場合は、ブランドごとに個別のクラスではなく、列挙型を使用します。

于 2012-10-26T19:00:35.637 に答える