设置后的空对象引用

本文关键字:对象引用 设置 | 更新日期: 2023-09-27 18:13:36

我试着用一小段代码来解释我的情况:

Class A
{
   private IDBTransaction trans;
   private IDBConnection conn;
   void Main()
   {
       B test = new B(trans)
       [some instruction]
       trans = conn.BeginTrans();
       test.Save();
   }
}
Class B
{
   private IDBTransaction trans;
   public B(IDBTransaction transaction)
   {
      trans = transaction;
   }
   void Save()
   {
      [some instruction that use transaction]
   }
}

当Save()被调用时,变量B.trans被设置为null,因为在A传递参数时它是空的。然后A.trans调用BeginTrans()改变它的值,但B.trans仍然保持为空。我该如何解决?

设置后的空对象引用

您可以将事务保存在单独的对象中,如

class TransactionInfo
{
    public IDbTransaction Transaction;  
    public IDbConnection conn;
}

,然后以这种方式使用

class A
{
    private static TransactionInfo info = new TransactionInfo();        
    static void Main()
    {
        B test = new B(info);
        //[some instruction]
        info.Transaction = info.conn.BeginTransaction();
        test.Save();
    }
}
class B
{
    private TransactionInfo _info;
    public B(TransactionInfo info)
    {
        _info = info;
    }
    public void Save()
    {
        //[some instruction that use transaction]
        _info.Transaction;
    }
}

OR你可以延迟这一刻,当你想要获得交易

public class ValueSource<T>
{
    private Func<T> _acessor;
    public ValueSource(Func<T> acessor)
    {
        _acessor = acessor;
    }
    public T Value
    {
        get 
        { 
            try 
            {
                return _acessor();
            }
            catch
            {
                return default(T);
            }
        }
    }
}

然后将上述任一解传递给构造函数。延迟示例(用于在单独的类中保持的示例相同)

class A
{
    private static IDbTransaction trans;
    private static IDbConnection conn;
   static void Main()
   {
        B test = new B(new ValueSource<IDbTransaction>(()=>trans));
        //[some instruction]
        trans = conn.BeginTransaction();        
        test.Save();
    }
}
class B
{
    private ValueSource<IDbTransaction> trans;
    public B(ValueSource<IDbTransaction> transactionSource)
   {
        trans = transactionSource;
    }
   public void Save()
   {
      //[some instruction that use transaction]
      trans.Value;
   }
}

上面的所有例子只适用于由于某种原因想要在B类中保留事务引用的情况。如果没有必要,我建议(正如在问题的评论中建议的那样)将事务作为Save方法参数传递。

class A
{
    private static  IDbTransaction Transaction;
    private static  IDbConnection conn;
    static void Main()
    {
        B test = new B();
        //[some instruction]
        Transaction = conn.BeginTransaction();
        test.Save(Transaction);
    }
}
class B
{
    public B()
    {       
    }
    public void Save(IDbTransaction transaction)
    {
        //[some instruction that use transaction]
        transaction
    }
}

只是要记住:不要在数据结构中存储任何东西,如果不是真的必要的话。没有状态的类包含更少的错误,并且更容易测试。

我会将trans作为参数传递给Save()方法而不是构造函数,在具有较长生命周期的对象上持有事务引用有点无用。(至少比事务长)这样您就可以在不同/多个事务上使用Save(trans)方法。

void Main()
{
    B test = new B();
    [some instruction]
    trans = conn.BeginTrans();
    test.Save(trans);
}

 Class B
 {
    void Save(IDBTransaction transaction)
    {
    }
}