System.Data.SqlClient.SqlTransaction
(封印された)を継承したいとします。私はちょうどSqlTransaction
の周りにラッパーを入れて、SqlTransaction
の代わりに常にMyTransaction
を使用したいと思います。 Implicit/Widening演算子を使用してMyTransaction
をSqlTransaction
にキャストする方法はありますか?C#/ VB.NETで継承をFAKEする方法はありますか?
答えて
別のオプションがある場合は、Reflection.Emit()を使用して、選択したインターフェイスをSqlTransactionに追加してから、新しいMyTransactionクラスでその同じインターフェイスを使用し、クラスの代わりにインターフェイスを呼び出すことができます。
これは、作成したライブラリ内でのみ機能します。または、Reflectionを使用してロードされたタイプを特に変更することに注意してください。
内部トランザクション変数を持つクラスを作成し、メソッドとプロパティを公開することができます。種類のこのような:
public class MyTransaction
{
System.Data.SqlTransaction myTx = someConnection.CreateTransaction();
public void CommitTransaction() : {
myTx.CommitTransaction()
}
}
ます。また、それはDbTransactionから継承し、その後、内側myTx変数を使用するように抽象的で仮想手続きを書き換える作ることができ、それは明白な本当の理由のために少し複雑になって開始します...
絶対に! : - しかし、もし人がトランザクションをラップしたいなら、理由があるかもしれません! –
彼はそれをやりたいと思うからといって、それが可能であっても、彼はすべきではありません。 –
@Ramhound私は同意しますが、それでもこのような解決策が適している他の適切なケースを習得するには良い方法です –
クラスにメソッドを追加するだけの場合は、拡張メソッドを使用できます。これで内部状態にアクセスすることはできませんし、動作を上書きすることもできますが、限られた機能を追加することができます。私は封印されたクラスから継承する方法を知らない。
他にも述べたとおり、真のラッパーオブジェクトを作成できますが、元のオブジェクトの代わりに多態的に使用することはできません。
これは.NET 2.0で拡張メソッドはありません...しかし、作成以来のものなので、拡張メソッドはとにかく動作しません。 – Denis
これは.net 2のために重要ではありませんが、拡張メソッドは、拡張メソッド(操作されているオブジェクト)の最初のパラメータをキーにした辞書を使用して、独立したオブジェクトデータを追跡できます。これにより、内部状態に似ているがオブジェクトの外部に格納されたデータの「パーティション化」セットを提供できます。内部のメンバーにはリフレクションを介してアクセスできるので、コードを手に入れようとしている「醜い」方法に応じて、面白いことをすることができます。 –
私はあなたが気にしないことを願っていますが、他の人がフレームワークのバージョンが限られていることを知るように.net2.0タグをあなたの質問に追加しました。 –
独自のMyTransactionクラスをSqlTransactionのラッパーとして定義できます。 MyTransaction内のプライベートフィールドにSqlTransactionのインスタンスを保持します。あなたのラッパーはSqlTransactionとの互換性はありませんが、SqlTransactionが実装しているインターフェイスと同じインターフェイスを実装すれば、かなり近づくことができます。
これもうまくいくと思っていましたが、SqlClientのようなものがあります。本当に、私はこのクエストを開始した偽のこれまでいくつかの方法が必要SUXのSqlTransaction、ないIDbTransactionを望んでいるSQLCommand.Transaction ... – Denis
いいえ、カスタムクラスをSqlTransactionから継承したり、これを偽装したりすることはできません。
ただし、DbTransactionを使用することができるコンテキストでは、DbTransactionからカスタムトランザクションクラスを継承し、必要な機能をSqlTransaction内にラップすることができます。あなたが
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;
}
}
私はうんこれも動作しますが、その後、あなたがのSqlTransaction – Denis
を望んでいるSqlClient.SQLCommand.Transactionのようなものを持っていると思いましたラップされたオブジェクトの全体ラットネストに入ります...あなたはSystem.Data名前空間のすべてのカスタムラッパーをSQLバージョンをラップすることができます。それはあなたの要件が何であるか、なぜこれらのオブジェクトを最初の場所。目標を達成する他の(より良い)方法がありそうです。 –
:(それはIMO、恐ろしいアイデアと恐ろしいデザインであるように私は、それをお勧めしませんが)、あなたはこのような何かを行うことができますあなたは本当には暗黙の型変換をしたい場合
また、これは特に汚い解決策です... –
私はReflection.Emit()を試みたことがありません。私は見回すつもりですが、これがどのように機能するかについての良い例やチュートリアルはありますか? – Denis
拡張メソッドを作成できます。
public static class SqlTransactionExtensions
{
public static void DoSomething(this SqlTransaction transaction, int myParameter)
{
// do something here
}
}
クラスは静的である必要があります。 fistパラメータの前に魔法の単語this
を置きます。これは、あなたが拡張しているクラスの型でなければなりません。インターフェイスを拡張することもできます。この拡張メソッドを使用する場合は、作業中の同じ名前空間に定義されていない場合は、この拡張クラスの名前空間にusing namspace
が必要です。それはのSqlTransactionの定期的な方法であったかのように
あなたはその後、拡張メソッドを呼び出すことができます。
SqlTransaction t = new SqlTransaction();
t.DoSomething(5);
これは誰かがここに提案した良いアイデアですが、これには2つの問題があります。(1).NET 2.0を使用しています。(2).NET 2.0を使用していない場合は、 SqlTransactionの作成? (このsqlTransactionを作成した人またはそれが開始された時刻を追跡するとします) – Denis
トランザクション用の静的ヘルパークラスを作成します。エクステンションクラスとよく似ていますが、 'this'キーワードはありません。 't.DoSomething(5);'でメソッドを呼び出すのではなく、 'TransactionsHelper.DoSomething(t、5);'でそれらを呼び出さなければなりません。拡張メソッドは実際には構文的な砂糖だけであり、通常のメソッドではできないことはできません。 –
OKので、継承を除外し、あなたが本当に解決したい課題に焦点を当て、(コメントに基づいて、スレッド)。
私は過去にすべての呼び出しをヘルパーライブラリで実行し、そのロジックを実装して成功しました。以前は、Microsoft Data Application Blockに掲載されているSqlHelperを使用しました。これはあなたのニーズに適応できるソースモジュールです。必要なロギングやその他のロジックを追加できます。
また、コードを非常に読みやすくします。 (INSERT
年代のように)何のリターンを持っていないコマンドに対して単一の値を返すクエリのためのデータセット、
SqlHelper.ExecuteScalar()
を返すクエリの
SqlHelper.ExecuteDataset()
、
SqlHelper.ExecuteNonQuery()
:あなたのようなことを行うことができます。
など
- 1. 継承を制限する方法はありますか?
- 2. C++でBoostマルチインデックスコンテナを継承する方法はありますか?
- 3. WPFでウィンドウを継承するより良い方法はありますか
- 4. Cでグループボックスを継承する方法
- 5. typescriptでutil.promisifyでメソッドシグネチャを継承する方法はありますか?
- 6. PHPサブクラスにプロパティ(継承とインスタンスの両方)を継承させる方法はありますか?
- 7. VB.netは2クラスを継承します
- 8. MultiLevel継承、クラスCはクラスAを継承できますか?
- 9. コードファーストフルーエントマッピングで継承プロパティを必要とする方法はありますか?
- 10. サブタスクがorg-modeで期限を継承する方法はありますか?
- 11. VB.netの継承
- 12. C#継承継承でbaseまたはthisを使用する
- 13. FAKEではビルドログ全体を取得する方法はありますか?
- 14. このjavascriptパターンを継承する方法はありますか?
- 15. JAX-RS/Jersey:@Providerフィールドを "継承"する方法はありますか?
- 16. VB.Net継承とインターフェイス
- 17. UML - クラス継承、あなたは何を継承しますか?
- 18. Objective-Cにプロトコルバッファをラップし、引き続き継承を利用する方法はありますか?
- 19. 継承の混乱vb.net
- 20. C#で継承されたクラスプロパティをオーバーライドする方法は?
- 21. ウィジェットのCSSスタイルシートを継承しない方法はありますか?
- 22. "接頭辞の継承"を防ぐ方法はありますか?
- 23. Cで継承するコントロール
- 24. VB.NETの継承に関するトラブル
- 25. .NETのインターフェイス継承/階層 - より良い方法がありますか?
- 26. IE7で "継承"のCSSサポートはありますか?
- 27. 子プロセスはfork()を使用して親プロセスからのデータを継承する方法はありますか?
- 28. C++の継承コンストラクタを書く方法
- 29. C#List <baseClass> - 継承されたクラスを格納する方法もありますか?
- 30. スタイルシートを継承する方法は?
'私はあなたがこのような何かをしたいと思う理由System.Data.SqlClient.SqlTransaction' =>を継承するとしますか? –
ダーリンは正しいです。最初に鋼鉄桁に穴が必要な理由を教えてくれるのではなく、掘削を求めています。タイプが封印されているという事実は、私があなたがこの中から継承したくないという大きな赤旗です。なぜあなたはクラスのデザイナーの希望に反して作業しようとしていますか?彼らはあなたの最大の利益を心に持っています。あなたが本当に達成したいことを説明してください。なぜなら、密閉されたクラスから継承することは起こり得ないからです。 –
リフレクションを使用してクラスの開封を行うことはできませんか? –