C#中的克隆

克隆(Clone)一个类实例(完全拷贝)的思想不是C#的固有属性,但也没有什么理由可以阻
止你自己完成这样的操作。克隆方法出现在C#中的惟一地方是在ADO Dataset处理里。读者可以
创建一个DataSet作为数据库查询的结果,其行指针可以一次移动一行。如果出于某种原因,需要
把索引保持在DataSet的两个位置上,就需要两个“当前行”。C#处理这种情况的最简单方法是克
隆DataSet。

DataSet cloneSet;
cloneSet=myDataSet.Clone();

这种方法并不产生数据的两个拷贝,它只生成两套行指针,用于在记录之间相互独立地移动。
因为实际上只有一个数据表,所以,DataSet的一个克隆体中的任何改变,都会立即反映到另一个
克隆体中。我们在下面的例子中会讨论一个与此类似的问题。

使用原型

我们接下来编写一个简单的程序,从数据库读人数据,然后克隆结果对象。在这个例子中,与
前面的论述一样,原始数据是从一个大数据库中导出来的,而我们只是从一个文件读人数据。文件
具有如下格式:

Kristen Frost, 9, CAT, 26.31, F 
Kimberly Watcke, 10, CDEV, 27.37, F 
Jaclyn Carey, 10, ARAC, 27.53, F 
Megan Crapster, 10, IEHY, 27.68, F 

这里要用到先前开发的csFiIe类。首先,创建一个Swimmer类,它包含一个运动员的名字、
俱乐部名字、性别和时间(即成绩),使用第4章开发的csFile类和StringTokenizer类读入这些
数据。

public class Swimmer
{
    private string name;
    private string lname,frname;
    private int age;
    private string club;
    private float time;
    private bool female;

    public Swimmer(string line)
    {
        StringTokenizer tok=new StringTokenizer(line,",");
        spliteName(tok);
        age=Convert.ToInt32(tok.nextToken());
        club=tok.nextToken();
        time=Convert.ToSingle(tok.nextToken());
        string sx=tok.nextToken().ToUpper();
        female=sx.Equals("F");
    }

    private void spliteName(StringTokenizer tck)
    {
        name=tok.nextToken();
        int i=name.IndexOf(" ");
        if(i>0)
        {
            frname=name.Substring(0,i);
            lname=name.Substring(i+1).Trim();
        }
    }

    public bool isFemale()
    {
        return female;
    }

    public int getAge()
    {
        return age;
    }

    public float getTime()
    {
        return time;
    }

    public string getName()
    {
        return name;
    }

    public string getClun()
    {
        return club;
    }
}

接下来创建一个SwimData类,它包含一个从数据库读人的swimmer对象的ArrayList。

public class SwimData
{
    protected ArrayList swdata;
    private int index;

    public SwimData()
    {
        swdata=new ArrayList();
    }

    public SwimData(ArrayList swd)
    {
        swdata=swd;
        index=0;
    }

    public SwimData(string filename)
    {
        swdata=new ArrayList();
        csFile f1=new csFile(filename);
        fl.openForRead();
        string s=fl.readLine();
        while(s!=null)
        {
            Swimmmer sw=new Swimmmer();
            swdata.Add(sw);
            s=fl.readLine();
        }
        fl.close();
    }

    public void moveFirst()
    {
        index=0;
    }

    public bool hasMoreElements()
    {
        return(index<swdata.Count-1);
    }

    public void sort()
    {

    }

    public Swimmmer getSwimmer()
    {
        if(index<swdata.Count)
            return (Swimmmer)swdata[index++];
        else 
            return null;
    }
}

然后,就可以使用该类读人选手数据,并把它们显示在列表框中。

private void init()
{
    swdata=new SwimData("swimmers.txt");
    reload();
}

private void reload()
{
    lsKids.Items.Clear();
    swdata.moveFirst();
    while(swdata.hasMoreElements())
    {
        Swimmer sw=swdata.getSwimmer();
        lsKids.Items.Add(sw.getName());
    }
}

单击“一>”按钮,克隆Swata类,并在新类中对数据进行不同的排序。因为创建一个新的
类实例会比较慢,而且我们想以两种形式保存数据,所以也对数据进行了克隆。

private void btClone_Click(object sender,EventArgs e)
{
    SwimData newSd=(SwimData)swdata.Clone();
    newSd.Sort();
    while(newSd.hasMoreElements())
    {
        Swimmer sw=(Swimmer)newSd.getSwimmer();
        lsNewKids.Items.Add(sw.getName());
    }
}
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐