Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to FAKE inheritance in C#/VB.NET?

Suppose I want to inherit from System.Data.SqlClient.SqlTransaction which is sealed. Supose I want to just put a wrapper around SqlTransaction and always use MyTransaction instead of SqlTransaction. Is there a way I could potentially cast MyTransaction to SqlTransaction using an Implicit/Widening operator?

like image 293
Denis Avatar asked Dec 14 '11 19:12

Denis


4 Answers

You could create a class that has an inner transaction variable and then expose the methods and properties. Kind of like this:

public class MyTransaction
{
    System.Data.SqlTransaction myTx = someConnection.CreateTransaction();

    public void CommitTransaction() :  {
        myTx.CommitTransaction()
    }
}

You could also make it inherit from DbTransaction and then rewrite the abstract and virtual procedures to use the inner myTx variable, but it starts getting a little complex for no apparent real reason...

like image 51
Alejandro B. Avatar answered Sep 30 '22 18:09

Alejandro B.


If you really want implicit conversion (although I would not recommend it, as it is a horrible idea and a horrible design, IMO), you can do something like this:

    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;
        }
    }
like image 28
Marty Avatar answered Sep 30 '22 18:09

Marty


If you are just interested in adding additional methods to a class you could use extension methods. That won't give you access to any internal state, or allow you to override behaviors, but it will let you add limited functionality. I'm not aware of any way to inherit from a sealed class.

You could create a true wrapper object as others have mentioned, but you won't be able to use it polymorphically in place of the original object.

like image 42
Bradley Uffner Avatar answered Sep 30 '22 20:09

Bradley Uffner


OK, so ruling out the inheritance and focusing on the task you really want to solve (based on the comment threads).

I have had success in the past running all calls through a helper library and implementing the logic there. In the past, I have used SqlHelper, which is published in the Microsoft Data Application Block. This is a source module, which you can adapt to your needs. You can add whatever logging or other logic you require.

It also makes the code very readable. You can do things like:

SqlHelper.ExecuteDataset() for queries returning sets of data,

SqlHelper.ExecuteScalar() for queries returning single values,

SqlHelper.ExecuteNonQuery() for commands which have no returns (like INSERT's).

etc.

like image 30
Tevo D Avatar answered Sep 30 '22 18:09

Tevo D