0

I used Extract Method on this code because there were multiples of this code, and here is what it became:

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;
    }
}

The only problem is, instead of the Chrome type parameter, I have created multiple instances of different classes, and I need to pass each one, for example, I have

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

etc. Now, how can I modify my parameter so that instead of Chrome, I can pass Chrome, Firefox, IE, etc. all in the same parameter, one at a time?

4

4 回答 4

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)

于 2012-08-12T22:18:22.887 回答
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字段来识别它。那么你真的不需要条件。

于 2012-08-12T22:18:54.497 回答
1

您的所有类型都是浏览器,这意味着您可以(并且应该)重构您的代码,以便它们都派生自一个共享的 Browser 类,如果它还不是这样的话。一旦你这样做了,你可以多态地改变你的方法:

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

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

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

class Browser
{
}

class IE : Browser
{
}

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

IE ie = new IE();

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

 Browser ie = new IE();

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

于 2012-08-12T22:20:43.893 回答
0

让他们都实现一个接口:

interface Browser
{

}

class Firefox : Browser
{

}
class IE : Browser
{

}

Browser ie = new IE();
//...
public void someMethod(Browser b)
//...
于 2012-08-12T22:19:16.930 回答