5

この投稿は、C# クラスに関する私の理解のギャップと、それらが静的関数よりも優れている理由を説明します。

オブジェクトのリストを取得しようとしています。リスト内の各オブジェクトは、テーブル内のレコードを表します。これは、静的関数で簡単に実行できます。

クラスを使用して、次のようにすることができました。

呼び出しルーチン:

ListOfBusinesses l = new ListOfBusinesses ();
List<Business> b = l.listBusinesses();

クラス:

 public class Business
 {
    public string Bupk { get; set; }
    public string Bu_name { get; set; }

 }  

 public class ListOfBusinesses
 {
    public List<Business> listBusinesses()
    {

      List<Business> businesses = new List<Business>();
      businesses.Add(new Business("1", "Business Name 1"));
      businesses.Add(new Business("2", "Business Name 2"));

      return businesses;
    }
 }

これを1行で実行できるようにクラスを書き直すことはできませんでした:

ListOfBusinesses l = new ListOfBusinesses();

上記の ListofBusinesses クラスは、プロパティを持たず、クラスを持つためだけに存在するクラスにラップされた静的関数にすぎないように思えます。

私は試した:

public class ListOfBusinesses
{
    List<Business> businesses;

    public List<Business> ListOfBusinesses()
    {

      List<Business> businesses = new List<Business>();
      businesses.Add(new Business("1", "Business Name 1"));
      businesses.Add(new Business("2", "Business Name 2"));

      return businesses;
    }
}

しかし、「メンバー名はそこに含まれる型と同じにすることはできません」というコンパイラエラーを受け取りました。たとえば、コンストラクターを使用しようとしましたが、何かが不足しています。

何か助けがあれば、私がしばらくの間誤解していた分野で私を啓発するでしょう.

マイク・トーマス

4

10 に答える 10

9

静的関数、コンストラクター、およびファクトリメソッドの概念を混同していると思います。

静的関数

意味

thisこれは、クラスのインスタンスにアクセスできない(そして関連付けられていない)メソッドです。

public class BusinessHelper
{   
    public static List<Business> ListBusinesses()
    {

        List<Business> businesses = new List<Business>();
        businesses.Add(new Business("1", "Business Name 1"));
        businesses.Add(new Business("2", "Business Name 2"));

        return businesses;
    }
}

使用法

クラスのインスタンスではなく、クラス名を使用して静的メソッドを呼び出します。

List<Business> businesses = BusinessHelper.ListBusinesses();

コンストラクタ:これはthis、クラスのインスタンスを作成するメソッドです。戻り値はなく、オブジェクトがインスタンス化されたときに呼び出されます。

public class BusinessList
{   
    public List<Business> TheList;

    public BusinessList()
    {    
        TheList = new List<Business>();
        TheList.Add(new Business("1", "Business Name 1"));
        TheList.Add(new Business("2", "Business Name 2"));   
    }
}

使用法

オブジェクトの新しいインスタンスを作成します。

BusinessList myBusinessList = new BusinessList();
businesses = myBusinessList.TheList;

ファクトリメソッド

意味

これは、オブジェクトのインスタンスを作成し、それを何らかの方法でインスタンス化し、そのオブジェクトへの参照を返すメソッドです。

public class BusinessList
{   
    public List<Business> TheList;

    public static BusinessList BusinessListWithTwoCompanies()
    {
        BusinessList instance = new BusinessList();

        businesses = new List<Business>();
        businesses.Add(new Business("1", "Business Name 1"));
        businesses.Add(new Business("2", "Business Name 2"));

        return instance;
    }
}

使用法

新しいオブジェクトを作成する代わりに、ファクトリメソッドを呼び出します。

BusinessList myBusinessList = BusinessList.BusinessListWithTwoCompanies();
businesses = myBusinessList.TheList;

さらに注意すべき2つのこと:

  1. フィールドを宣言しますが、メソッドで呼び出された別の変数のbusinessesインスタンス化に進み、それを返します。フィールドには何も起こりません。可変スコープに注意してください。businessesListOfBusinesses()businesses

  2. クラスと同じ名前のメンバー(フィールド、プロパティ、またはメソッド)を持つことはできません。これは、戻り型を持たないコンストラクター用に予約されています(上記を参照)。これが、コンパイラエラーが発生する理由です。

于 2009-05-20T15:28:53.533 に答える
5

もちろん。をカプセル化する代わりにList<Business>、拡張します。次に、コンストラクターでそれに何かを追加するだけです。

public class ListOfBusinesses : List<Business> {
    public ListOfBusinesses() : base() {
        Add(new Business("1", "Business Name 1"));
        Add(new Business("2", "Business Name 2"));
    }
}

使用するには:

List<Business> l = new ListOfBusinesses();
于 2009-05-20T15:16:09.050 に答える
2

オブジェクトのインスタンス化は、すべての OO 言語で基本的に同じです。静的関数ではなくクラスを使用すると、特に多くの同様のアイテムを追跡する場合に、柔軟性が大幅に向上し、最終的にコーディングが少なくなります。

本や図書館を思い浮かべてください。

本をオブジェクト クラスとして持っている場合は、それをインスタンス化して多数の本を作成し、それらをライブラリに保存できます。あなたが主張したすべての本はユニークです。変更を加えていない場合、インスタンス化された各ブックはオリジナルのコピーのように見えます (ただし、低レベルでは、各ブックには一意のシリアル番号があります)。表紙、ページ数、内容は同じですが、1部に自分の名前を簡単に書くことができるので、他とは一線を画しています。

本を静的にすると、個々のコピーを作成することはできませんが、同じ本を別の視点から見ることになります。そこにあなたの名前を書くと、本のすべてのビューにあなたの名前が表示されます。

私がこれを入力している間は、他の多くの人があなたのビジネス オブジェクトのコード サンプルを投稿しているので、コードを投稿するつもりはありません。

于 2009-05-20T16:00:22.407 に答える
1

コンストラクタではなくファクトリ メソッドを探しています。

于 2009-05-20T15:14:35.697 に答える
1

クラス名が「ListOfBusinesses」で、メソッド名も「ListOfBusinesses」であるため、コンパイラ エラーが発生します。これはコンストラクターであれば問題ありませんが、戻り値の型があるため、C# はコンストラクターではなくメソッドであると考えています。

ビジネスのリストを取得するには、次のようなクラスを作成してください。

public class BusinessService {
   public List<Business> GetBusinesses() {
       // Build and return your list of objects here.
   }
}

それを使用するには:

BusinessService service = new BusinessService();
List<Business> businesses = service.GetBusinesses();
于 2009-05-20T15:16:19.610 に答える
1

コンストラクターのクラスとは異なるものを返そうとしています

public class ListOfBusinesses
{
    ...

    public List<Business> ListOfBusinesses()
    {
        ...

コンストラクターで戻り値の型を指定することはできません。次のものが必要です。

public ListOfBusinesses()
{
    ...

Mike Thomas が言ったように、それが必要な場合は、代わりにファクトリを使用する必要があります。

于 2009-05-20T15:19:13.503 に答える
0

問題は、クラスのコンストラクターを呼び出すために使用される予約語 (new) を使用していることです。

コンストラクターのセマンティックは、作成中のクラスのインスタンスを返すことであり、戻り値を持たず、クラスと同じ名前を持つという規則に従います。

そうでない場合、もしあなたが何かをするとしnew MyObjectたら...あなた(またはコンパイラー)はどのようにして戻り値の型を知ることになるのでしょうか?

于 2009-05-20T15:16:42.667 に答える
0

一般的に言えば、List<Business> で使用できないプロパティが ListOfBusinesses に含まれていない限り、ListOfBusinesses クラスを作成することはありません。これを処理する最も簡単な方法は、次のように Business クラスの静的メソッドです。

public class Business
{
    //Business class methods/properties/fields

    static List<Business> GetList()
    {
        List<Business> businesses = new List<Business>();
        businesses.Add(new Business("1", "Business Name 1"));
        businesses.Add(new Business("2", "Business Name 2"));
        return businesses;
    }
}

これは簡単な方法ですが、この方法をたどると、このメソッドを Business クラスからオブジェクト ファクトリにリファクタリングすることになります。オブジェクト ファクトリは通常、NHibernate や Castle Windsor などの ORM フレームワークを通じて提供されます。

于 2009-05-20T15:21:56.823 に答える
0

人々が前に言ったように、あなたの構文は正しくありません。ListOfBusiness()コンストラクターであり、明示的にオブジェクトを返しません。代わりに、の新しいインスタンスで動作し、ListOfBusiness必要な作成を処理する必要があります。

つまり、作成するメソッドList<Business>が単純であれば、それを静的メソッドの一部にする必要はまったくありません。List の拡張メソッドを定義して、空のリストを取り、それを設定することもできます。これは Factory パターンと呼ばれ、メソッドまたはオブジェクトのインスタンスが新しいインスタンスの作成を担当します。

インスタンス化されたクラスへの拡張を検討するListOfBusiness必要があるのは、追跡する必要があるプロパティまたは状態がある場合です。呼び出さList<Business>れるたびに が変更される場合、または新しいビジネスを追加する場所が必要な場合、ListOfBusinessクラスはそのために役立つ可能性があります。

于 2009-05-20T15:24:17.380 に答える
0

私が間違っていなければ、データベースにアクセスして、1 行の呼び出しでオブジェクトのリストを取得したいと考えています。

まず、db アクセスをカプセル化し、List メソッドを公開する DAO クラスが必要です。DAO 内では、NHibernate、Linq2XXX、または必要なものを使用できます (サンプル)

public class BusinessItem
{
    public string Code { get; set; }
    public string Description { get; set; }
}

public class BusinessItemsDAO
{
...
    public List<BusinessItem>   List()
    {
        // fake... should retrieve from db
        var list = new List<BusinessItem>();

        // returs the list
        return list;
    }
...
}

あなたのクライアントコードは単に呼び出すことができます

var listOfBusinessItems = new BusinessItemsDAO().List();

Linq が有効になっている場合は、リストの代わりに IQueryable を返すと役立ちます。

于 2009-05-20T16:25:23.607 に答える