8

C# を使用する Visual Studio 2008 で、複数のクラスとソース ファイル間でコードを共有する最良の方法は何ですか?

クラスにはすでに意味のある階層があるため、継承は解決策ではありません。

別のクラスの好きな場所にコードを挿入できる C インクルード ファイルのような便利な機能はありますか?

編集:

わかりました、具体例が必要だと思います...

ドメインには、よく考え抜かれたクラス階層を持つ数百のクラスがあります。現在、これらのクラスの多くは印刷する必要があります。印刷を処理するユーティリティ プリンター クラスがあります。印刷されるクラスに依存する 3 つの異なる印刷メソッドがあるとします。print メソッドを呼び出すコード (6 行) は、すべての異なるクライアント クラス ページでのコピー アンド ペーストを回避しようとしているものです。

特に、適合しない手法について具体的に言及する場合は...

4

10 に答える 10

8

非常に異なるものを表すクラスで頻繁に使用する機能がある場合、私の経験では、いくつかのカテゴリに分類する必要があります。

  • ユーティリティ (文字列の書式設定、解析など)
  • 分野横断的な懸念事項 (ロギング、セキュリティの実施など)

ユーティリティ タイプの機能については、別のクラスを作成し、必要に応じてビジネス クラスでユーティリティ クラスを参照することを検討する必要があります。

public class Validator
{
  public bool IsValidName(string name);
}

class Patient
{
  private Validator validator = new Validator();
  public string FirstName
  {
     set
     {
         if (validator.IsValidName(value)) ... else ...
     }
  }
}

ロギングやセキュリティなどの分野横断的な問題については、Aspect-Oriented Programmingを調査することをお勧めします。

他のコメントで説明されている PrintA と PrintB の例に関しては、Factory パターンの優れたケースのように思えます。IPrint を実装するクラス PrintA と PrintB などのインターフェイスを定義し、特定のページのニーズに基づいて IPrint のインスタンスを割り当てます。

// Simplified example to explain:

public interface IPrint 
{ 
   public void Print(string); 
}

public class PrintA : IPrint
{
   public void Print(string input)
   { ... format as desired for A ... }
}

public class PrintB : IPrint
{
   public void Print(string input)
   { ... format as desired for B ... }
}

class MyPage
{
   IPrint printer;

   public class MyPage(bool usePrintA)
   {
      if (usePrintA) printer = new PrintA(); else printer = new PrintB();
   }

   public PrintThePage()
   {
      printer.Print(thePageText);
   }
}
于 2009-12-10T03:49:51.540 に答える
7

C の場合のように、プリプロセッサ ディレクティブを介して C# のクラスに追加したいコードをロードすることはできません。

ただし、インターフェイスを定義し、そのインターフェイスの拡張メソッドを宣言することはできます。インターフェイスはクラスによって実装でき、それらのクラスで拡張メソッドを呼び出すことができます。例えば

public interface IShareFunctionality { }

public static class Extensions
{
    public static bool DoSomething(this IShareFunctionality input)
    {
        return input == null;
    }
}

public class MyClass : Object, IShareFunctionality
{
    public void SomeMethod()
    {
        if(this.DoSomething())
            throw new Exception("Impossible!");
    }
}

これにより、機能を再利用できますが、たとえばファイルをハッシュ インクルードできる場合のように、クラスのプライベート メンバーにアクセスすることはできません。

あなたがやりたいことの具体的な例が必要かもしれません。

于 2009-12-10T03:24:42.387 に答える
3

AC# ユーティリティ クラスが動作します。これは、一般的なコード (または VB.NET モジュール コンストラクト) の中央レジストリのように機能します。どのクラスにも固有ではないコードを含める必要があります。それ以外の場合は、関連するクラスに添付する必要があります。

必要がない場合は、ソースコードのコピーを開始したくありません。これは、重複を考慮したコード更新の問題につながるためです。

ソースが状態を保持する必要がない限り、静的メソッドで静的クラスを使用します。

static public class MySharedMembers {
    static public string ConvertToInvariantCase(string str)  {
        //...logic
    }
    // .... other members
}
于 2009-12-10T03:15:21.223 に答える
2

クラスが同じ名前空間にある場合、インクルード アナログは必要ありません。他の関数で定義されたクラスのメンバーを呼び出すだけです。

それらが同じ名前空間にない場合は、使用するクラスの名前空間を usings ディレクティブに追加すると、上記と同じように機能するはずです。

私は質問に混乱しています:基本的な OO の理解に取り組む必要があるようです。

于 2009-12-10T03:18:56.113 に答える
2

チェックアウト拡張メソッド: http://msdn.microsoft.com/en-us/library/bb383977.aspx

于 2009-12-10T03:19:56.033 に答える
2

ファイルの一部を含める方法はわかりませんが、よく行うことの 1 つは、既存のファイルを追加して現在の場所から「リンク」することです。たとえば、すべてのプロジェクトがソリューション ディレクトリから参照する assemblyInfo.cs ファイルがあります。一度変更すると、同じファイルを参照しているため、すべてのプロジェクトに同じ情報が含まれます。

それ以外の場合は、common.dll 内の「一般的な」ルーチンのリファクタリングに関する提案が、.Net で思いついた最良のものです。

于 2009-12-10T03:45:09.380 に答える
1

「意味のある」構造が何を意味するのか正確にはわかりませんが、これは基本クラスの実装を使用できる場所のように思えます。C++ の多重継承ほど「冗長」ではありませんが、チェーン化された基本クラスの実装を使用して一般的な関数を再利用すると、いくつかの利点が得られる場合があります。

少なくとも視覚的にはクラス階層を保持し、必要に応じて動作をオーバーライドできます。

于 2009-12-10T03:22:01.020 に答える
1

繰り返しコードをサービスに引き出します。コードの繰り返しは、リファクタリングの余地があるかもしれないという手がかりです。

たとえば、印刷に必要なロジックを含む「PrintingService」を作成します。次に、出力する必要があるクラスをこのサービスに依存させることができます (コンストラクターまたはサービスを必要とするメソッドのパラメーターを介して)。

これらの行に沿って私が持っているもう 1 つのヒントは、基本機能のインターフェイスを作成し、そのインターフェイスを使用してコーディングすることです。たとえば、ユーザーがファックス、電子メール、または印刷できるレポートクラスがたくさんありました。それぞれにメソッドを作成する代わりに、それぞれにサービスを作成し、Output() の単一のメソッドを持つインターフェイスを実装させました。次に、ユーザーが必要とする出力の種類に応じて、各サービスを同じメソッドに渡すことができます。顧客がモデムを介したファックスの代わりに eFax を使用したいと考えたとき、これと同じインターフェイスを実装する新しいサービスを作成するだけで済みました。

于 2009-12-10T04:37:45.003 に答える
0

正直なところ、Visual C# のインクルードのようなものは思い浮かびませんし、その機能が必要な理由もわかりません。そうは言っても、部分クラスはあなたが望むように何かをすることができますが、それらを使用すると、「クラスはすでに意味のある階層を持っている」という要件に反する可能性があります。

于 2009-12-10T03:17:07.537 に答える
0

多くのオプション、TT、拡張メソッド、デリゲート、およびラムダがあります

于 2009-12-10T03:32:18.340 に答える