[英]Is there a way to FAKE inheritance in C#/VB.NET?
假设我想继承密封的 System.Data.SqlClient.SqlTransaction
。 我希望只是在SqlTransaction
周围放置一个包装器,并始终使用MyTransaction
而不是SqlTransaction
。 有没有办法可以使用Implicit / MyTransaction
运算符将MyTransaction
为SqlTransaction
?
您可以创建一个具有内部事务变量的类,然后公开方法和属性。 有点像这样:
public class MyTransaction
{
System.Data.SqlTransaction myTx = someConnection.CreateTransaction();
public void CommitTransaction() : {
myTx.CommitTransaction()
}
}
你也可以让它继承自DbTransaction,然后重写抽象和虚拟程序以使用内部myTx变量,但它开始变得有点复杂,没有明显的真正原因......
如果您只是想为类添加其他方法,可以使用扩展方法。 这不会让您访问任何内部状态,或允许您覆盖行为,但它会让您添加有限的功能。 我不知道有什么方法可以继承密封课程。
您可以像其他人提到的那样创建一个真正的包装器对象,但是您将无法以多态方式使用它来代替原始对象。
如果你真的想要隐式转换(虽然我不推荐它,因为它是一个可怕的想法和一个可怕的设计,IMO),你可以做这样的事情:
class MyTransaction
{
private readonly SqlTransaction _transaction;
public MyTransaction(SqlConnection conn)
{
_transaction = conn.BeginTransaction();
}
public SqlTransaction Transaction
{
get
{
return _transaction;
}
}
public static implicit operator SqlTransaction(MyTransaction t)
{
return t.Transaction;
}
}
好的,所以排除了继承并专注于你真正想要解决的任务(基于评论线程)。
我过去成功通过帮助程序库运行所有调用并在那里实现逻辑。 过去,我使用过SqlHelper,它发布在Microsoft Data Application Block中 。 这是一个源模块,您可以根据自己的需要进行调整。 您可以添加所需的任何日志记录或其他逻辑。
它还使代码非常易读。 你可以这样做:
SqlHelper.ExecuteDataset()
用于返回数据集的查询,
SqlHelper.ExecuteScalar()
用于返回单个值的查询,
SqlHelper.ExecuteNonQuery()
用于没有返回的命令(如INSERT
的)。
等等
不,你不能让你的自定义类继承自SqlTransaction或伪造它。
但是,如果您正在执行的操作的上下文允许您使用DbTransaction,则可以从DbTransaction继承自定义事务类,使用您需要的任何其他功能将SqlTransaction包装在内部。
你有另一个选择,你可以使用Reflection.Emit()将你选择的接口添加到SqlTransaction,然后在你的新MyTransaction类中使用相同的接口然后你可以调用接口,而不是类。
请注意,这只能在您创建的库中使用,或者使用Reflection专门修改加载的类型。
您可以创建扩展方法。
public static class SqlTransactionExtensions
{
public static void DoSomething(this SqlTransaction transaction, int myParameter)
{
// do something here
}
}
该类必须是静态的。 将魔语this
其中一定是要扩展的类的类型的拳头参数的前面。 您也可以扩展接口。 如果要使用此扩展方法,则必须using namspace
具有此扩展类的命名空间的using namspace
,如果它未在您正在使用的同一命名空间中定义。
然后,您可以调用扩展方法,就像它是SqlTransaction的常规方法一样:
SqlTransaction t = new SqlTransaction();
t.DoSomething(5);
您可以将自己的MyTransaction类定义为SqlTransaction的包装器。 在MyTransaction中的私有字段中保留SqlTransaction的实例。 你的包装器不会与SqlTransaction兼容,但是如果实现SqlTransaction实现的相同接口,你可以非常接近。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.