Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我的秒表/timespan在整个方法中不保留其信息?_C#_Class_Abstract Class - Fatal编程技术网

C# 为什么我的秒表/timespan在整个方法中不保留其信息?

C# 为什么我的秒表/timespan在整个方法中不保留其信息?,c#,class,abstract-class,C#,Class,Abstract Class,我目前正在研究一个涉及抽象类和秒表的问题。我有两个类,SQL和Oracle。它们都使用字符串作为连接代码(这种东西实际上没有任何作用,但我正试图让它有点现实)。我想启动一个秒表,然后用另一种方法停止它-但时间跨度总是显示00:00 我是否正确访问父类的属性 我尝试在不同的地方初始化秒表和时间跨度 public class Program { public static void Main(string[] args) { // Con

我目前正在研究一个涉及抽象类和秒表的问题。我有两个类,SQL和Oracle。它们都使用字符串作为连接代码(这种东西实际上没有任何作用,但我正试图让它有点现实)。我想启动一个秒表,然后用另一种方法停止它-但时间跨度总是显示00:00

我是否正确访问父类的属性

我尝试在不同的地方初始化秒表和时间跨度

public class Program
    {
        public static void Main(string[] args)
        {
           // ConnectionManagement management = new ConnectionManagement();
           // management.SetUpOptions();


        }
    }

    public class ConnectionManagement
    {
        public void SetUpOptions()
        {
            while (true)
            {
                SqlConnection sqlGatherer = new SqlConnection("placeholder");
                OracleConnection oracleGatherer = new OracleConnection("placeholder");

                Console.WriteLine("1. Open an SQL connection.");
                Console.WriteLine("2. Close an SQL connection.");
                Console.WriteLine("3. Open an Oracle connection.");
                Console.WriteLine("4. Close an SQL connection.");
                string choice = Console.ReadLine();

                if (choice == "1")
                {
                    Console.WriteLine("Enter your connection string.");
                    string enteredConnectionString = Console.ReadLine();
                    sqlGatherer.ConnectionString = enteredConnectionString;
                    sqlGatherer.OpenConnection();
                }
                else if (choice == "2")
                {
                    sqlGatherer.CloseConnection();
                }
                else if (choice == "3")
                {
                    Console.WriteLine("Enter your connection string.");
                    string enteredConnectionString = Console.ReadLine();
                    oracleGatherer.ConnectionString = enteredConnectionString;
                    oracleGatherer.OpenConnection();
                }
                else if (choice == "4")
                {
                    oracleGatherer.CloseConnection();
                }
                else
                {
                    Console.WriteLine("That was not a valid option.");
                }
            }

        }
    }

    public abstract class DataBaseConnection
    {

        public string ConnectionString { get; set; }
        public TimeSpan Timeout { get; set; }
        public Stopwatch OracleStoppy { get; set; }
        public Stopwatch SqlStoppy { get; set; }
        public abstract void OpenConnection();
        public abstract void CloseConnection();

    }

    public class SqlConnection : DataBaseConnection
    {

        private bool CurrentConnection = false;

        public SqlConnection()
        {
            Timeout = new TimeSpan();
            SqlStoppy = new Stopwatch();
        }

        public SqlConnection(string connectionString)
        {

            Timeout = new TimeSpan();
            SqlStoppy = new Stopwatch();
            if (connectionString == null || String.IsNullOrWhiteSpace(connectionString))
            {
                throw new ArgumentException("Program has an invalid SQL connection string.");
            }
            else
            {
                this.ConnectionString = connectionString;
            }
        }

        public override void OpenConnection()
        {
            if (CurrentConnection == true)
            {
                throw new Exception("A connection has already been established.");
            }
            else
            {
                Console.WriteLine("SQL connection established.");
                SqlStoppy.Start();
                CurrentConnection = true;

            }

        }

        public override void CloseConnection()
        {
            if (CurrentConnection == false)
            {
                SqlStoppy.Stop();
                TimeSpan reportedTimeout = Timeout;
                Console.WriteLine("Connection closed. \nThe connection was active for {0}", reportedTimeout);
                SqlStoppy.Reset();
                CurrentConnection = false;

            }
            else
            {
                throw new Exception("There is no SQL connection to close.");
            }

        }
    }

    public class OracleConnection : DataBaseConnection
    {
        private bool CurrentConnection = false;

        public OracleConnection()
        {
            Timeout = new TimeSpan();
            OracleStoppy = new Stopwatch();
        }

        public OracleConnection(string connectionString)
        {
            Timeout = new TimeSpan();
            OracleStoppy = new Stopwatch();
            if (connectionString == null || String.IsNullOrWhiteSpace(connectionString))
            {
                throw new Exception("Program has an invalid Oracle connection string.");
            }
            else
            {
                this.ConnectionString = connectionString;
            }
        }
        public override void OpenConnection()
        {
            if (CurrentConnection == true)
            {
                throw new Exception("A connection has already been established.");
            }
            else
            {
                Console.WriteLine("Oracle connection established.");
                OracleStoppy.Start();
                CurrentConnection = true;
            }

        }

        public override void CloseConnection()
        {
            if (CurrentConnection == false)
            {
                throw new Exception("There is no Oracle connection to close.");
            }
            else
            {
                OracleStoppy.Stop();
                this.Timeout = OracleStoppy.Elapsed;
                Console.WriteLine("Connection closed. \nThe connection was active for {0}", Timeout);
                OracleStoppy.Reset();
                CurrentConnection = false;
            }

        }
    }

关闭打开的连接后,该方法应打印打开的时间或秒表持续时间。同样的问题也发生在我的CurrentConnection变量上,所以我把它作为私有变量放在每个类中。但是,让这样的父类具有其子类可以交互的公共属性不是很重要吗

问题

我看到在oracle中,您有:

this.Timeout = OracleStoppy.Elapsed;
Console.WriteLine("Connection closed. \nThe connection was active for {0}", Timeout);
但在sql中:

TimeSpan reportedTimeout = Timeout;
Console.WriteLine("Connection closed. \nThe connection was active for {0}", reportedTimeout);
这应该是

this.Timeout = SqlStoppy.Elapsed;
Console.WriteLine("Connection closed. \nThe connection was active for {0}", Timeout);
不是吗

建议

您使用一个父类,所以不需要两个秒表,只需要一个秒表,否则继承就没用了,您需要重复代码

<>你应该考虑删除一些设置器。

并移动受保护的重复连接

这应该是:

public abstract class DataBaseConnection
{
    protected bool CurrentConnection;

    public string ConnectionString { get; }
    public TimeSpan Timeout { get; }
    public Stopwatch Stoppy { get; }
    public abstract void OpenConnection();
    public abstract void CloseConnection();

    public DataBaseConnection()
    {
      Timeout = new TimeSpan();
      Stoppy = new StopWatch();
    }
}
还可以在构造函数之间使用调用模式:

public OracleConnection()
{
  ...
}

public OracleConnection(string connectionString)
  : this()
{
  ...
}
你重复了太多相同的代码,你真的应该重构和更好的抽象东西

重复代码时,您可以:

  • 创建一个方法并调用它,而不是重复代码

  • 有时您可以在父类中移动它

当变量在子类中重复时,可以将其删除,以便在父类中只有一个变量

您可以使用诸如
public
private
protected
internal
abstract
virtual
override

您还应该重命名一些变量,使其更加一致和连贯

规则是一个名字必须是简单的,并且准确地指定它是什么

例如,
Chrono
可能比
Stoppy
更好,
index
indexRow
i
更好

因此,这里的
持续时间
经过时间
可能比指示停止连接尝试的延迟的
超时
要好

另外,由于类名为
Connection
,因此不需要指定
OpenConnection
CloseConnection
Open
Close
就足够了

也许你会发现这很有用:

您没有在
SqlConnection
类中使用,您只是简单地打印
Timeout
的值,该值总是
0
,因为您从未给它赋值。