在功能结束或超出范围后,是否可以重置静态字段?

时间:2018-07-13 08:35:00

标签: c#

我有多种类型的Component类和1个Generator类。组件类具有一个名称字段,当由生成器类生成时,它必须是唯一的。

因此,我将组件类和生成器类编写如下:

public class Component_A{
    static int iCount;
    public string name {get;set;}
    public Component_A(){
        name = String.Format("ComponentA_{0}", iCount++);
    }
}

public class Component_B{
    static int iCount;
    public string name {get;set;}
    public Component_A(){
        name = String.Format("ComponentB_{0}", iCount++);
    }
}

public class Generator(){
    public List<String> generateComponent(){
        Component_A a1 = new Component_A();
        Component_A a2 = new Component_A();
        Component_B b1 = new Component_B();

        List<string> strList = new List<string>();
        strList.Add(a1.name);
        strList.Add(a2.name);
        strList.Add(b1.name);

        return strList;
    }
}

public class MainClass(){
    public static void main(){
        Generator gen;
        for(int i=0; i<2; i++){
            gen = new Generator();
            List<String> componentNameList = gen.generateComponent();

            foreach(var s in componentNameList){
                Console.Out.WriteLine(s);
            }
            Console.Out.WriteLine();
        }

    }
}

但是,我想在初始化新生成器时重置组件iCount字段。

例如:上面的代码执行结果是:

ComponentA_0
ComponentA_1
ComponentB_0

ComponentA_2
ComponentA_3
ComponentB_1

但是我希望它像这样:

ComponentA_0
ComponentA_1
ComponentB_0

ComponentA_0
ComponentA_1
ComponentB_0

我怎么能做到这一点?

3 个答案:

答案 0 :(得分:0)

public class Component_A{
    public static int iCount;
    public string name {get;set;}
    public Component_A(){
        name = String.Format("ComponentA_{0}", iCount++);
    }
}

public class Component_B{
    public static int iCount;
    public string name {get;set;}
    public Component_A(){
        name = String.Format("ComponentB_{0}", iCount++);
    }
}

public class Generator(){
    public List<String> generateComponent(){
        Component_A a1 = new Component_A();
        Component_A a2 = new Component_A();
        Component_B b1 = new Component_B();

        List<string> strList = new List<string>();
        strList.Add(a1.name);
        strList.Add(a2.name);
        strList.Add(b1.name);

        return strList;
    }
    public void reset() {
        Component_A.iCount = 0;
        Component_B.iCount = 0;
    }
}

只需将iCount更改为public,并添加一种重置方法即可将iCount更改为0。

像这样使用它:

public class MainClass(){
    public static void main(){
        Generator gen;
        for(int i=0; i<2; i++){
            gen = new Generator();
            List<String> componentNameList = gen.generateComponent();

            foreach(var s in componentNameList){
                Console.Out.WriteLine(s);
            }
            gen.reset();
            Console.Out.WriteLine();
        }

    }
}

编辑:由于您有100多个组件,因此反射似乎是一个不错的选择。我已经将组件移到了自己的类中。

public class Components{
    public class Component_A{
        public static int iCount;
        public string name {get;set;}
        public Component_A(){
            name = String.Format("ComponentA_{0}", iCount++);
        }
    }

    public class Component_B{
        public static int iCount;
        public string name {get;set;}
        public Component_B(){
            name = String.Format("ComponentB_{0}", iCount++);
        }
    }
}

public class Generator {
    public List<String> generateComponent(){
        var a1 = new Components.Component_A();
        var a2 = new Components.Component_A();
        var b1 = new Components.Component_B();

        List<string> strList = new List<string>();
        strList.Add(a1.name);
        strList.Add(a2.name);
        strList.Add(b1.name);

        return strList;
    }
    public void reset() {
        var components = typeof(Components).GetNestedTypes().ToList();
        foreach (var component in components) {
            var property = component.GetField("iCount", BindingFlags.Public | BindingFlags.Static);
            property.SetValue(null, 0);
        }
    }
}

答案 1 :(得分:0)

我不会创建一个负责命名自己的组件,而是创建一个NameGenerator类,该类具有一个根和(可选)起始编号,并公开NextName

public class NameGenerator {
    private int _next;
    private readonly string _nameRoot;
    public NameGenerator(string nameRoot) : this (nameRoot, 0)
    {}
    public Namegenerator(string nameRoot, int firstNumber)
    {
        _next = firstNumber;
        _nameRoot = nameRoot;
    }
    public string NextName()
    {
        return String.Format("{0}_{1}", _nameRoot,_next++);
    }
}

您的Generator类现在应该拥有一组这些对象(取决于您是急切还是懒惰地初始化它们),并且您的Component类应该具有一个接受{{ 1}}随地吐痰。

NameGenerator

答案 2 :(得分:0)

似乎您愿意计算每个生成器实例生成的A或B组件,而不仅仅是计算A或B组件的总数。

所以您应该将计数器放在生成器实例中:

public class Component_A{
    public string name {get;set;}
    public Component_A(int count){
        name = String.Format("ComponentA_{0}",  count);
    }
}
public class Component_B{
    public string name {get;set;}
    public Component_B(int count){
        name = String.Format("ComponentB_{0}", count);
    }
}
public class Generator{
    private int iCountA=0;
    private int iCountB=0;
    private Component_A createComponentA()
    {
        return new Component_A(iCountA++);
    }
    private Component_B createComponentB()
    {
        return new Component_B(iCountB++);
    }
    public List<String> generateComponent(){
        Component_A a1 = createComponentA();
        Component_A a2 = createComponentA();
        Component_B b1 = createComponentB();
        List<string> strList = new List<string>();
        strList.Add(a1.name);
        strList.Add(a2.name);
        strList.Add(b1.name);
        return strList;
    }
}

这是输出(主代码保持不变):

ComponentA_0
ComponentA_1
ComponentB_0

ComponentA_0
ComponentA_1
ComponentB_0