简体   繁体   English

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

[英]C# - Pass different types as one Parameter

I used Extract Method on this code because there were multiples of this code, and here is what it became: 我在此代码上使用了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;
    }
}

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 唯一的问题是,我创建了多个不同类的实例,而不是Chrome类型参数,并且需要传递每个实例,例如,我有

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? 等等。现在,我该如何修改我的参数,以使我可以一次将一个参数传递给Chrome,Firefox,IE等,而不是Chrome。

Have the different browsers inherit from a base Browser class (or implement a common interface) and pass that in. 让不同的浏览器继承自基本的Browser类(或实现通用接口)并将其传递。

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

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

    public abstract void NavigateTo(URL url);
}

Then implement the browsers and their specific functionality as needed: 然后根据需要实现浏览器及其特定功能:

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

Rewrite your method to take the Browser and promote whatever shared properties are necessary to that base class: 重写您的方法以使用Browser并提升该基类所需的所有共享属性:

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

Your best bet is to create a common interface type that the browser classes can implement (something like IBrowser ). 最好的选择是创建浏览器类可以实现的通用接口类型(类似于IBrowser )。 Then your method signature becomes: 然后,您的方法签名将变为:

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

And within the method you'll have to add some conditional logic to figure out which type it is: 在该方法中,您将必须添加一些条件逻辑来确定它是哪种类型:

if(browser is Firefox)
{
...
}

Of course, if the browser types all do the same thing, you should probably just have one Browser class that has some sort of UserAgent field to identify it. 当然,如果所有浏览器类型都执行相同的操作,则您可能应该只有一个Browser类,该类具有某种UserAgent字段来标识它。 Then you really don't need the conditional. 那么您真的不需要条件了。

All your types are browsers, which means that you can (and should) refactor your code so that they all derive from one shared Browser class, if it's not already like this. 您所有的类型都是浏览器,这意味着您可以(并且应该)重构代码,以便它们都源自一个共享的Browser类(如果还不是这样)。 Once you do this, you can polymorphically change your method: 完成此操作后,您可以对方法进行多态更改:

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

If you are unwilling to do this then the only other solution I can think of is overloading the method. 如果您不愿意这样做,那么我能想到的唯一其他解决方案就是重载该方法。

This article supplies information about inheritance in C#. 本文提供有关C#中的继承的信息。 Basically, what you do is: 基本上,您要做的是:

class Browser
{
}

class IE : Browser
{
}

You can then still initialize IE like this: 然后,您仍然可以像这样初始化IE:

IE ie = new IE();

But you can also initialize it polymorphically like this: 但是您也可以像这样多态初始化它:

 Browser ie = new IE();

If you derive more classes from Browser, such as Firefox, Chrome, etc. then you can treat them all as a single type, Browser, inside a method. 如果您从浏览器派生出更多类,例如Firefox,Chrome等,则可以将它们全部视为一种方法内的单一类型浏览器。

Have them all implement an interface: 让它们全部实现一个接口:

interface Browser
{

}

class Firefox : Browser
{

}
class IE : Browser
{

}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM