跨类的某些实例但不是其他实例的静态/共享变量

时间:2012-10-26 18:54:15

标签: c# .net vb.net

这可能只是我表现出我缺乏知识/糟糕的编程习惯,但我很想知道是否: a)这已经存在 b)如果它不存在,那么编程实践是不好的

但这是我的问题:

假设我有一个类,我们称之为“计算机”,它包含公司中所有计算机的数据。现在,恰巧这家公司拥有数千台戴尔电脑和数千台惠普,而不是别的。 (再次请在这里坚持我,这只是一个例子来说明我的观点)

现在,我可以按如下方式定义我的课程:

Public Class Computer

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

End Class

现在,在我的代码中,我创建了两个列表:

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

显然,对于DellComps,所有人都有.Type = "Dell"而对于HPComps,所有人都有.Type = "HP"

现在,我知道我可以很容易地在构造函数中设置这个变量,但是我想知道是否有更聪明的方法在类中声明变量 - 类似于VB Shared / C#Static语句,其中所有实例该类共享相同的变量。

我的想法是:

  1. 继承该类并在子类
  2. 中创建共享变量
  3. 保持原样,并在构造函数中声明Type var
  4. 也许这可以通过界面以某种方式完成
  5. 最可能 - 我不知道的事情
  6. 谢谢,我希望我的要求有道理!!!

3 个答案:

答案 0 :(得分:5)

您最接近的事情是abstract关键字。您将拥有一个抽象类Computer,然后由具体的子类DellComputerHpComputer覆盖。粗略的(C#)示例是:

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

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

您通常不希望在大量实例中共享单个变量,因为这会破坏封装,并且在尝试单元测试代码时更加逼真地成为一个大问题。所以你所谈论的纯粹形式并不是一个非常好的主意,但实际的用例非常普遍,并且肯定得到了支持。

编辑:作为以下评论的一部分,这是一种使用密切相关的virtual关键字的不同方法!

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

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

答案 1 :(得分:2)

如果你总是在构造函数中设置一个标志来指示计算机的类型(这不是典型的业务对象场景,可以编辑类型),那么很可能你可以使用子类来解决你的问题。

子类用于创建DellComputer和HpComputer类的计算机。

创建每种类型计算机的列表时,一种方法是拥有所有计算机的主列表,并使用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);

答案 2 :(得分: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;}
}

关于静态变量。您不希望班级的所有成员共享Brand。

用上述内容重复构造函数中的数据 如果戴尔具有与HP相同的属性,那么我将使用相同的类 如果你说购买一个新品牌,你真的想创建一个新的类或子类吗? 如果你想要一个结构化的品牌列表,那么我会使用和Enum而不是每个品牌的单独的类。