2

この質問が正確に何であるかわかりません。

これが問題です。ソース コードを使用せずにアセンブリにパックして製品として出荷するフレームワークに取り組んでいるとします。フレームワークは最初から拡張性を念頭に置いて開発されています。つまり、一部のターゲット ドメインの詳細/データ/クラスは、フレームワークを参照するエンド ユーザー/アセンブリによって定義されます。これを有効にする方法の 1 つは、フレームワークでジェネリックを使用して、後ですべてを定義することです。ただし、ジェネリックが単一のクラスに導入されると、すべての依存/参照クラスとメソッドは、すべての正確な制約を使用してそれを再宣言する必要があります。単一のジェネリックを渡すことは大したことではありませんが、対処しなければならない場合、たとえば 8 つのジェネリックを処理する必要がある場合、物事はすぐに制御不能になります。これはまったく珍しいことではありません。フレームワークの小さなクラスごとに、すべてのクラスで同じである再宣言された型パラメーターを数行配置する必要があります。すべての(ほとんどの)クラスに同じジェネリック宣言を追加するある種の c++ のようなマクロを用意するだけで、手早く汚い解決策が得られるようです。ただし、C# にはマクロがないため、手動で行う必要があります。ここで問題になります。これらのパラメーターを大かっこから取り出して、アセンブリ (プロジェクト) レベルで一度宣言するにはどうすればよいでしょうか? 「public class Entity*」と書く必要がないように ただし、C# にはマクロがないため、手動で行う必要があります。ここで問題になります。これらのパラメーターを大かっこから取り出して、アセンブリ (プロジェクト) レベルで一度宣言するにはどうすればよいでしょうか? 「public class Entity*」と書く必要がないように ただし、C# にはマクロがないため、手動で行う必要があります。ここで問題になります。これらのパラメーターを大かっこから取り出して、アセンブリ (プロジェクト) レベルで一度宣言するにはどうすればよいでしょうか? 「public class Entity*」と書く必要がないように< TField> * { ... }" です。これは、TField が定義されており、それが表示されるたびに、クラスがアセンブリ レベルと同じ宣言を使用して暗黙的に認識していることを意味するためです。このような汎用アセンブリをリンクすることにより、開発者は次のことを行う必要があります。使用できるようになる前にすべての型引数を提供するか、一部のパラメーターがまだバインドされていない場合は、後で使用するためにそれらを再宣言します。

質問:

  • このような状況に陥ったことがありますか?
  • この機能があると便利だと思いますか?
  • もしそうなら、あなたは現在それなしでどのように過ごしていますか?
  • c# に取り組んでいる人向け: これを c# の新しいバージョンに追加する可能性はありますか?

ありがとうございました!

アップデート:

あまり詳細には触れたくありませんでしたが、お望みどおりにしました。わかりやすい例を作るのは難しいので、現在の状況を共有させてください。私はテキスト処理フレームワークに取り組んでおり、テキストをトークン化し、それに一致するすべての可能なパターンを持つコア ライブラリがあります。何も知らないのは、名詞や動詞などの品詞の扱い方です。幸いなことに、それを行うことができる別のアセンブリがあります。ここでの目標は、コア ライブラリのパターンを別のライブラリの品詞の知識で拡張することです。私が行った方法は、「CustomPattern」という名前のコアライブラリに特別なパターンを追加したことです。これは、任意のクラスによってパラメーター化され、何にでも置き換えることができます。私たちの場合、それは PartOfSpeach enum です。https://gist.githubでコードのパッセージを見てください。.

ここで質問です。コア ライブラリに TDetails ジェネリックが含まれないようにしつつ、任意のデータが付加されたカスタム パターンを使用できるようにする方法を教えてください。

ここでの唯一の要件は、現在のコードを厳密に型付けしておく必要があるということです。

4

3 に答える 3

4

私はあなたが提示するシナリオが好きではありませんが、別のオプションはネストされたタイプです:

public sealed class Foo<T> where T : Whatever {
    public class Bar { ... }

    public interface IBlap { ... }
}

内部のすべてのタイプは、制約を複製する必要なしFoo<T>に、に暗黙的にアクセスできます。Tコード管理の目的で、これを複数のファイルに分割することができます。ここでも、制約について1回だけ言及します。

// file 1
partial class Foo<T> where T : IWhatever
{

}
// file 2
partial class Foo<T>
{
    public class Bar
    { ... }
}
// file 3
partial  class Foo<T>
{
    public interface IBlap
    { ... }
}

ただし、最初に、シナリオを健全性チェックします。

于 2012-05-10T06:03:10.050 に答える
4

このような状況に陥ったことがありますか?

はい。

この機能があると便利だと思いますか?

悪用の可能性があるため、「グローバル」なものには警戒していますが、クラス間で一般的な制約を定義/共有できると便利だと思います。

もしそうなら、あなたは現在それなしでどのように過ごしていますか?

私は、ジェネリックを使いすぎる傾向があり、それらは便利ですが、すべてのタスクに最適であるとは限りません。

最近、フレームワーク ライブラリの 1 つを WCF 対応にする作業に着手しました。私が書き終える頃には、ほぼすべてのジェネリック インターフェイスが作り直されているか、ジェネリックではない同等のインターフェイスが作成されていました。これは、操作コントラクトとデータ コントラクトとしてより適切に機能するようにインターフェイスを簡素化する必要があるためでしたが、終了するまでに、デザインがよりクリーンで直感的になり、あきらめることはほとんどなかったと結論付けました。

設計を評価すると、入力パラメーターが基本型またはインターフェイスから継承することを要求することで、制約の厳しいジェネリック インターフェイスを置き換えることができることがわかる場合があります。

たとえば、型パラメーター TField1 が Foo 型のインスタンス化可能なクラスでなければならない場合、インターフェースを Foo (またはそのサブクラスの可能性が高い) を要求するように変更しないのはなぜでしょうか?

public void Act<TField> where TField : Foo, new() { }

になる

public void Act( Foo f ) { } 

また

public void Act( IFoo f ){ }

クラスが入力オブジェクトに基づいて動作するように設計されている場合、通常、クラスはオブジェクトのメンバーと能力についてある程度の知識を持っている必要があります。

たとえば、List<T>( T obj )実際には入力値を他の方法で保存する必要はあまりありませんが、おそらくTransferMoneyFromAccount<TAccount>( TAccount obj )入力データに対して非常に具体的なことを行う必要があります。おそらく次のように変更される可能性がありますTransferMoneyFromAccount( IAccount obj )

あなたのライブラリの消費者にとって、インターフェイスはジェネリックよりもはるかにエレガントにコントラクトの考え方を強制すると思います。

c# に取り組んでいる人向け: これを c# の新しいバージョンに追加する可能性はありますか?

c# に取り組んでいる人 (Eric Lippert) から:

コンパイラがこの機能またはその機能を実装しない理由をよく尋ねられますが、もちろん答えは常に同じです。誰も実装していないからです。機能は実装されていない状態から始まり、人々がそれらを実装するのに労力を費やした場合にのみ実装されます。努力がなければ、機能はありません。

出典: http://blogs.msdn.com/b/ericlippert/archive/2012/03/09/why-not-automatically-infer-constraints.aspx (偶然にも、ジェネリック型制約に関する記事)

于 2012-05-10T05:41:37.217 に答える
1

あなたの質問は非常に一般的です(しゃれは意図されていません)。つまり、一般的な答えが得られます。

私は拡張性を念頭に置いたいくつかのフレームワークを開発しました(私のプロファイルを確認してください)。そして、それを達成するためにジェネリックを使用する必要はありませんでした。imhoジェネリックは、汎用クラスの型安全性を取得するために使用されます。

インターフェイスは、拡張性のためのフレームワークを設計するために使用する必要があるものです。

(誤解した場合はQを更新してください)

于 2012-05-10T05:59:06.727 に答える