簡體   English   中英

不了解C#中的對象實例化

[英]Not Understanding Object Instantiation in C#

這篇文章對我對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;
    }
 }

我不能重寫這個類,這樣就可以用一行來完成:

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;
    }
}

但收到編譯器錯誤“成員名稱不能與封閉類型相同”。 例如,我試圖使用構造函數,但我遺漏了一些東西。

在我誤解了一段時間的地方,任何幫助都會啟發我。

邁克托馬斯

我認為你混淆了靜態函數,構造函數和工廠方法的概念。

靜態功能

定義

這是一個無法訪問(並且不與之關聯) 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;

另外要注意兩件事:

  1. 您聲明了一個businesses字段,但繼續在ListOfBusinesses()方法中實例化另一個名為businesses變量並將其返回。 businesses領域什么都不會發生。 小心變量范圍。

  2. 您不能擁有與該類同名的成員(字段,屬性或方法)。 這是為構造函數保留的,它沒有返回類型(參見上文)。 這就是您收到編譯器錯誤的原因。

當然。 而不是封裝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();

對於所有OO語言,對象實例化基本相同。 使用類而不是靜態函數可以提供更大的靈活性,並最終減少編碼,尤其是在跟蹤許多類似項目時。

想想書籍和圖書館。

如果您將該書作為對象類,則可以將其實例化以創建大量書籍並將其存儲在庫中。 你已經實施的每本書都是獨一無二的。 如果您沒有對其進行任何更改,則每個實例化的圖書似乎都是原始圖書的副本(盡管在較低級別,每本圖書都有唯一的序列號)。 它具有相同的封面,頁數和內容,但您可以輕松地將您的名字寫在一個副本中,從而使其與其他副本不同。

如果你使這本書成為靜態的,那么雖然你不能創建單獨的副本,但是你看的是同一本書,但是從不同的角度來看。 如果您在其中寫下您的名字,那么您的名字就會出現在本書的每個視圖中。

我不會發布任何代碼,因為在我打字的時候,很多其他代碼已經為您的業務對象發布了代碼示例。

您正在尋找工廠方法而不是構造函數。

您的編譯器錯誤是因為您的類名是“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();

你試圖在構造函數中返回與類不同的東西

public class ListOfBusinesses
{
    ...

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

您無法在構造函數中指定返回類型,您需要:

public ListOfBusinesses()
{
    ...

正如邁克托馬斯所說,如果那是你想要的,你應該使用工廠。

問題是你正在使用一個用於調用的構造函數的保留字(new)。

構造函數的語義是返回正在創建的類的實例,它遵循沒有返回值並且具有相同名稱的類的規則。

如果不是那樣的話,那么,如果你做了任何new MyObject ......你(或編譯器)應該知道返回的類型嗎?

一般來說,除非ListOfBusinesses具有List <Business>中不可用的某些屬性,否則不會創建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框架提供。

正如人們之前所說的那樣 - 你的語法不正確。 ListOfBusiness()是一個構造函數,不顯式返回一個對象。 它改為在ListOfBusiness的新實例上ListOfBusiness並且應該處理任何必要的創建。

也就是說 - 如果創建List<Business>很簡單,那么絕對沒有理由將它作為靜態方法的一部分。 您甚至可以在List上定義一個擴展方法,該方法獲取一個空列表並填充它。 這稱為工廠模式,其中對象的方法或實例負責創建新實例。

如果存在需要跟蹤的屬性或狀態,那么您希望將ListOfBusiness擴展到實例化類中的位置。 如果List<Business>每次調用時都會更改,或者如果您需要添加新業務的位置,則ListOfBusiness類可能對此有用。

如果我沒錯,你想訪問一個數據庫並通過一行調用檢索一個對象列表。

首先,您需要一個封裝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而不是List可能會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM