为什么我的 stopwatch/timespan 没有在整个方法中保留其信息?
Why is my stopwatch/timespan not retaining its information throughout methods?
我目前正在处理一个涉及抽象 classes 和秒表的问题。我有两个 classes,SQL 和 Oracle。它们都采用一个字符串作为连接代码(这些东西实际上没有做任何事情,但我试图让它有点现实)。我想启动秒表,然后以不同的方法停止它 - 但时间跨度总是显示 00:00...
我是否正确访问了父 class 的属性?
我已经尝试在不同的地方初始化我的秒表和时间跨度。
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 变量上,所以我把它作为私有变量放在每个 class 中。但是,让父 class 这样的父 class 具有其子 class 可以与之交互的共同属性的意义不是吗?
问题
我看到在 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);
不是吗?
建议
你使用了父级 class,所以你不需要两个秒表,只需要一个,否则继承是无用的,你重复代码。
你也应该考虑删除一些 setter。
并移动重复的 CurrentConnection,作为保护。
这应该是:
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()
{
...
}
你重复了太多相同的代码,你真的应该重构和更好地抽象东西。
当代码重复时,您可以:
创建一个方法并调用它,而不是重复代码。
有时您可以将其移动到父级 class。
当变量在子 classes 中重复时,您可以删除它们以在父 class.
中只有一个
您可以使用 public
、private
、protected
、internal
、abstract
、virtual
、override
...
您还应该重命名一些变量,使其更加一致和连贯。
规则是名称必须简单并且准确指定它是什么。
例如 Chrono
可能比 Stoppy
和 index
更好,或者 indexRow
比 i
更好。
所以这里 Duration
或 Elapsed
可能比 Timeout
更好,后者指示停止连接尝试的延迟。
另外因为 classes 被命名为 Connection
你不需要指定 OpenConnection
和 CloseConnection
: Open
和 Close
足够了。
也许你会发现这很有用:
What is polymorphism
我目前正在处理一个涉及抽象 classes 和秒表的问题。我有两个 classes,SQL 和 Oracle。它们都采用一个字符串作为连接代码(这些东西实际上没有做任何事情,但我试图让它有点现实)。我想启动秒表,然后以不同的方法停止它 - 但时间跨度总是显示 00:00...
我是否正确访问了父 class 的属性?
我已经尝试在不同的地方初始化我的秒表和时间跨度。
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 变量上,所以我把它作为私有变量放在每个 class 中。但是,让父 class 这样的父 class 具有其子 class 可以与之交互的共同属性的意义不是吗?
问题
我看到在 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);
不是吗?
建议
你使用了父级 class,所以你不需要两个秒表,只需要一个,否则继承是无用的,你重复代码。
你也应该考虑删除一些 setter。
并移动重复的 CurrentConnection,作为保护。
这应该是:
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()
{
...
}
你重复了太多相同的代码,你真的应该重构和更好地抽象东西。
当代码重复时,您可以:
创建一个方法并调用它,而不是重复代码。
有时您可以将其移动到父级 class。
当变量在子 classes 中重复时,您可以删除它们以在父 class.
中只有一个您可以使用 public
、private
、protected
、internal
、abstract
、virtual
、override
...
您还应该重命名一些变量,使其更加一致和连贯。
规则是名称必须简单并且准确指定它是什么。
例如 Chrono
可能比 Stoppy
和 index
更好,或者 indexRow
比 i
更好。
所以这里 Duration
或 Elapsed
可能比 Timeout
更好,后者指示停止连接尝试的延迟。
另外因为 classes 被命名为 Connection
你不需要指定 OpenConnection
和 CloseConnection
: Open
和 Close
足够了。
也许你会发现这很有用:
What is polymorphism