假设我想继承{strong}密封的System.Data.SqlClient.SqlTransaction
。我希望只在SqlTransaction
周围放一个包装,并始终使用MyTransaction
而不是SqlTransaction
。有没有办法可以使用Implicit / Widening运算符将MyTransaction
投射到SqlTransaction
?
答案 0 :(得分:6)
您可以创建一个具有内部事务变量的类,然后公开方法和属性。有点像这样:
public class MyTransaction
{
System.Data.SqlTransaction myTx = someConnection.CreateTransaction();
public void CommitTransaction() : {
myTx.CommitTransaction()
}
}
你也可以让它从DbTransaction继承,然后重写抽象和虚拟程序以使用内部myTx变量,但它开始变得有点复杂,没有明显的真正原因......
答案 1 :(得分:3)
如果您只想为类添加其他方法,可以使用扩展方法。这不会让您访问任何内部状态,或允许您覆盖行为,但它会让您添加有限的功能。我不知道有任何方法可以从密封的班级继承。
您可以像其他人提到的那样创建一个真正的包装器对象,但是您将无法以多态方式使用它来代替原始对象。
答案 2 :(得分:3)
如果真的想要隐式转换(虽然我不推荐它,因为它是一个可怕的想法和一个可怕的设计,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;
}
}
答案 3 :(得分:2)
好的,所以排除继承并专注于你真正想要解决的任务(基于评论主题)。
过去我成功通过帮助程序库运行所有调用并在那里实现逻辑。过去,我使用的是SqlHelper,它发布在Microsoft Data Application Block中。这是一个源模块,您可以根据自己的需要进行调整。您可以添加所需的任何日志记录或其他逻辑。
它还使代码非常易读。你可以这样做:
SqlHelper.ExecuteDataset()
用于返回数据集的查询
SqlHelper.ExecuteScalar()
用于返回单个值的查询,
SqlHelper.ExecuteNonQuery()
表示没有返回的命令(如INSERT
)。
等
答案 4 :(得分:1)
不,你不能让你的自定义类继承自SqlTransaction或伪造它。
但是,如果你正在做的事情的上下文允许你使用DbTransaction,你可以从DbTransaction继承你的自定义事务类,用你需要的任何其他功能包装一个SqlTransaction。
答案 5 :(得分:1)
你还有另一种选择,你可以使用Reflection.Emit()将你选择的接口添加到SqlTransaction,然后在新的MyTransaction类中使用相同的接口,然后你可以调用接口该课程。
请注意,这只能在您创建的库中使用,或者使用Reflection专门修改加载的类型。
答案 6 :(得分:1)
您可以创建扩展方法。
public static class SqlTransactionExtensions
{
public static void DoSomething(this SqlTransaction transaction, int myParameter)
{
// do something here
}
}
该类必须是静态的。将魔术词this
放在第一个参数前面,该参数必须是您要扩展的类的类型。您也可以扩展接口。如果要使用此扩展方法,则必须具有此扩展类的命名空间的using namspace
,如果它未在您正在使用的同一命名空间中定义。
然后,您可以调用扩展方法,就像它是SqlTransaction的常规方法一样:
SqlTransaction t = new SqlTransaction();
t.DoSomething(5);
答案 7 :(得分:0)
您可以将自己的MyTransaction类定义为SqlTransaction的包装器。在MyTransaction中的私有字段中保留SqlTransaction的实例。你的包装器不会与SqlTransaction兼容,但是如果实现SqlTransaction实现的相同接口,你可以非常接近。