C# - 将不同类型作为一个参数传递

时间:2012-08-12 22:13:37

标签: c# parameter-passing

我在这段代码上使用了Extract Method,因为这段代码有多个,这就是它的成就:

private void InsertStatement(string table, string table2, TestURLGUI4.Form1 form, SQLiteConnection sql_con, ref int dbID, ref int dbID2, Chrome chrome, int max)
{
    try
    {
        List<int> dbIDs = new List<int>();
        using (SQLiteTransaction mytransaction = sql_con.BeginTransaction())
        {
            using (SQLiteCommand mycommand = new SQLiteCommand(sql_con))
            {
                mycommand.CommandText = "insert or ignore into " + table + " (id, url, title, visit_count, frecency, last_visit_date) values (@dbID,@url,@title,@visit,@frecency,@time)";

                for (var count2 = 0; count2 < chrome.URLs.Count; count2++)
                {
                    URL u = chrome.URLs[count2];
                    mycommand.Parameters.Add(new SQLiteParameter("@dbID", dbID));
                    mycommand.Parameters.Add(new SQLiteParameter("@url", u.url));
                    mycommand.Parameters.Add(new SQLiteParameter("@title", u.title));
                    mycommand.Parameters.Add(new SQLiteParameter("@visit", u.frequency));
                    mycommand.Parameters.Add(new SQLiteParameter("@time", ToPRTime(u.visited)));
                    mycommand.Parameters.Add(new SQLiteParameter("@frecency", ToFrecency(u.frequency)));
                    mycommand.ExecuteNonQuery();
                    dbIDs.Add(dbID);
                    dbID++;
                    form.label1.Text = count2 + "/" + max;
                    Application.DoEvents();
                }

            }
            mytransaction.Commit();
        }
        using (SQLiteTransaction mytransaction = sql_con.BeginTransaction())
        {
            using (SQLiteCommand mycommand = new SQLiteCommand(sql_con))
            {
                mycommand.CommandText = "insert or ignore into " + table2 + " (id, from_visit, place_id, visit_date, visit_type, session) values (@dbID2,2,@dbID,@time,1, 0)";

                for (var count2 = 0; count2 < chrome.URLs.Count; count2++)
                {
                    URL u = chrome.URLs[count2];
                    mycommand.Parameters.Add(new SQLiteParameter("@dbID2", dbID2));
                    mycommand.Parameters.Add(new SQLiteParameter("@dbID", dbIDs[count2]));
                    mycommand.Parameters.Add(new SQLiteParameter("@time", ToPRTime(u.visited)));
                    mycommand.ExecuteNonQuery();
                    dbID2++;
                    form.label1.Text = count2 + "/" + max;
                    Application.DoEvents();
                }

            }
            mytransaction.Commit();
        }
    }
    catch
    {
        throw;
    }
}

唯一的问题是,我创建了不同类的多个实例,而不是Chrome类型参数,我需要传递每个实例,例如,我有

IE ie = new IE();
Firefox firefox = new Firefox();

等。现在,我如何修改我的参数,以便我可以在同一个参数中一次一个地传递Chrome,Firefox,IE等Chrome,而不是Chrome?

4 个答案:

答案 0 :(得分:2)

让不同的浏览器从基类Browser类继承(或实现一个通用接口)并将其传入。

public abstract class Browser
{
    public List<URL> URL { get; private set; }

    protected Browser
    {
        URL = new List<URL>();
    }

    public abstract void NavigateTo(URL url);
}

然后根据需要实现浏览器及其特定功能:

public class InternetExplorer : Browser
{
    private Random rand = new Random();
    public override void NavigateTo(URL url)
    {
        if (rand.NextDouble() < 0.5)
            throw new InvalidOperationException();
        else
            url.Navigate();
    }   
}

public class Firefox : Browser
{
    public override void NavigateTo(URL url)
    {
        Thread.Sleep(250);
        url.Navigate();
    }
}

public class Chrome : Browser
{
    public override void NavigateTo(URL url)
    {
        url.Navigate();
        GoFaster();
    }
}

重写您的方法以获取Browser并提升该基类所需的任何共享属性:

private void InsertStatement(string table, string table2, TestURLGUI4.Form1 form, SQLiteConnection sql_con, ref int dbID, ref int dbID2, Browser browser, int max)

答案 1 :(得分:2)

最好的办法是创建一个浏览器类可以实现的通用接口类型(类似IBrowser)。然后您的方法签名变为:

private void InsertStatement(string table, string table2, TestURLGUI4.Form1 form, SQLiteConnection sql_con, ref int dbID, ref int dbID2, IBrowser browser, int max)

在该方法中,您必须添加一些条件逻辑来确定它是哪种类型:

if(browser is Firefox)
{
...
}

当然,如果浏览器类型都做同样的事情,你应该只有一个Browser类,它有一些UserAgent字段来识别它。那你真的不需要条件。

答案 2 :(得分:1)

您的所有类型都是浏览器,这意味着您可以(并且应该)重构您的代码,以便它们都来自一个共享的浏览器类,如果它不是这样的话。完成此操作后,您可以通过多种方式更改方法:

private void InsertStatement(string table, string table2, TestURLGUI4.Form1 form, SQLiteConnection sql_con, ref int dbID, ref int dbID2, Browser browser, int max)

如果您不愿意这样做,那么我能想到的唯一其他解决方案就是重载该方法。

This article提供有关C#中继承的信息。基本上,你所做的是:

class Browser
{
}

class IE : Browser
{
}

然后你可以像这样初始化IE:

IE ie = new IE();

但你也可以像这样多态地初始化它:

 Browser ie = new IE();

如果您从浏览器中派生出更多类,例如Firefox,Chrome等,那么您可以在方法中将它们全部视为单一类型,浏览器。

答案 3 :(得分:0)

让他们都实现一个接口:

interface Browser
{

}

class Firefox : Browser
{

}
class IE : Browser
{

}

Browser ie = new IE();
//...
public void someMethod(Browser b)
//...