[英]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;
另外要注意兩件事:
您聲明了一個businesses
字段,但繼續在ListOfBusinesses()
方法中實例化另一個名為businesses
變量並將其返回。 businesses
領域什么都不會發生。 小心變量范圍。
您不能擁有與該類同名的成員(字段,屬性或方法)。 這是為構造函數保留的,它沒有返回類型(參見上文)。 這就是您收到編譯器錯誤的原因。
當然。 而不是封裝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.