0

このコードには複数のコードがあったため、このコードで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の代わりに、Chrome、Firefox、IEなどをすべて同じパラメータで一度に1つずつ渡すことができるように、パラメータを変更するにはどうすればよいですか?

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の何らかのフィールドを持つクラスが1つだけあるはずです。UserAgentそうすれば、条件付きは本当に必要ありません。

于 2012-08-12T22:18:54.497 に答える
1

すべてのタイプはブラウザーです。つまり、コードをリファクタリングして、まだこのようになっていない場合は、すべてが1つの共有ブラウザークラスから派生するようにすることができます(また、そうする必要があります)。これを行うと、メソッドを多形的に変更できます。

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();

Firefox、Chromeなど、ブラウザからさらに多くのクラスを派生させる場合は、メソッド内でそれらすべてを単一のタイプであるブラウザとして扱うことができます。

于 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 に答える