[英]Object Initializer vs Constructor in C# when many arguments are required
我正在開發一個框架,以從C#應用程序訪問EVE Online API。 本質上,API通過客戶端向EVE Online服務器發送GET請求來工作,然后服務器以XML文件的形式發送響應。 我的框架將這些XML文件中的信息解析為對象。 來自請求的信息無法修改(即,無法從客戶端應用程序更改服務器數據)。 因此,對象本身必須是不可變的。
現在,如果您要看這里 ,您會看到有許多不同的字段將始終隨每個請求一起發送。 例如,如果您要請求角色的電子錢包交易,則需要
char/WalletTransactions
哪個會返回這樣的東西
<?xml version='1.0' encoding='UTF-8'?>
<eveapi version="2">
<currentTime>2010-12-10 22:10:45</currentTime>
<result>
<rowset name="transactions" key="transactionID" columns="transactionDateTime,transactionID,quantity,typeName,typeID,price,clientID,clientName,stationID,stationName,transactionType,transactionFor">
<row transactionDateTime="2010-11-24 20:33:00" transactionID="1625396969" quantity="2" typeName="Armor Plates" typeID="25605" price="314004.67" clientID="1429013925" clientName="DDV 77" stationID="60008992" stationName="Lisudeh IV - Moon 4 - Theology Council Tribunal" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-17 00:15:00" transactionID="1617616497" quantity="2393" typeName="Phased Plasma S" typeID="184" price="14.90" clientID="979676146" clientName="Kaihokohoko McIver" stationID="60001174" stationName="Lisudeh VI - Moon 2 - Kaalakiota Corporation Factory" transactionType="buy" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:58:00" transactionID="1613691673" quantity="1" typeName="Survey Scanner I" typeID="444" price="1113.09" clientID="90001413" clientName="Lucius Ventrell" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:57:00" transactionID="1613691609" quantity="2" typeName="Ship Scanner I" typeID="443" price="501.00" clientID="1612349330" clientName="Homer911" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:57:00" transactionID="1613691547" quantity="1" typeName="Rudimentary Ship Scanner I" typeID="6527" price="10.00" clientID="1551104262" clientName="Chloe TaTu" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:57:00" transactionID="1613691498" quantity="2" typeName="150mm Railgun I" typeID="565" price="5002.10" clientID="419113578" clientName="Rashim Xanadu" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:57:00" transactionID="1613691447" quantity="1" typeName="Small Hull Repairer I" typeID="524" price="14103.98" clientID="703468457" clientName="Orgazzmic" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:57:00" transactionID="1613691402" quantity="1" typeName="Dual Light Beam Laser I" typeID="452" price="3009.91" clientID="703468457" clientName="Orgazzmic" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:57:00" transactionID="1613691357" quantity="1" typeName="Small Nosferatu I" typeID="530" price="8106.77" clientID="703468457" clientName="Orgazzmic" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:56:00" transactionID="1613690953" quantity="4" typeName="Small Energy Transfer Array I" typeID="529" price="13511.27" clientID="703468457" clientName="Orgazzmic" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:56:00" transactionID="1613690800" quantity="7" typeName="Tripped Power Circuit" typeID="25598" price="90852.35" clientID="467910905" clientName="Galloway Gallegher" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
<row transactionDateTime="2010-11-13 05:56:00" transactionID="1613690762" quantity="1" typeName="Tangled Power Conduit" typeID="25594" price="275.83" clientID="1271418001" clientName="Garthmanx" stationID="60004516" stationName="Hek IV - Krusual tribe Bureau" transactionType="sell" transactionFor="personal" />
</rowset>
</result>
<cachedUntil>2010-12-10 22:25:45</cachedUntil>
</eveapi>
我需要的對象需要具有每一行的所有這些字段(transactionDateTime,transactionID,數量,typeName,typeID,價格,clientID,clientName,stationID,stationName,transactionType,transactionFor),因此它看起來像
public class WalletTransaction
{
public string TransactionDateTime { get; private set; }
public int TransactionID { get; private set; }
public int Quantity { get; private set; }
public string TypeName { get; private set; }
public int TypeID { get; private set; }
public decimal Price { get; private set; }
public int ClientID { get; private set; }
public string ClientName { get; private set; }
public int StationID { get; private set; }
public string StationName { get; private set; }
public Type TransactionType { get; private set; }
public Account TransactionFor { get; private set; }
public int JournalTransactionID { get; private set; }
public WalletTransaction(string transactionDateTime, int transactionID,
int quantity, string typeName, int typeID, decimal price, int clientID,
string clientName, int stationID, string stationName, Type transactionType,
Account transactionFor, int journalTransactionID)
{
TransactionDateTime = transactionDateTime;
TransactionID = transactionID;
Quantity = quantity;
TypeName = typeName;
TypeID = typeID;
Price = price;
ClientID = clientID;
ClientName = clientName;
StationID = stationID;
StationName = stationName;
TransactionType = transactionType;
TransactionFor = transactionFor;
JournalTransactionID = journalTransactionID;
}
public enum Type
{
Buy,
Sell
}
public enum Account
{
Personal,
Computer
}
}
如您所見,這是一個龐大的構造函數,但是除非對象具有從XML文件接收到的所有信息,否則它不會完全初始化。 還有許多其他類似的對象,需要以這種方式運行(不可變,具有許多不同的字段)
因此問題就變成了:由於對象必須是不可變的,並且需要具有所有這些不同的字段,因此我需要使用構造函數嗎? 還是在這種情況下,對象初始化程序會更好一些,如果他們確實願意,只讓他們調用setter方法,因為這對服務器沒有任何影響?
從數據源(SQL,文件,XML等)創建對象時,我最喜歡做的事情之一就是構造一個使用數據源本身的構造函數。
在您的情況下,可以使構造函數或靜態工廠方法采用XmlNode(或表示事務),並負責從源本身讀取值。
兩種方法的示例:
public class WalletTransaction
{
public string TransactionDateTime { get; private set; }
public int TransactionID { get; private set; }
public int Quantity { get; private set; }
// More omitted for length
// FACTORY METHOD (RECOMMENDED)
public static WalletTransaction Create(XmlNode node)
{
return new WalletTransaction()
{
TransactionDateTime = node.Attributes["transactionDateTime"].Value,
TransactionID = int.Parse(node.Attributes["transactionID"].Value),
Quantity = int.Parse(node.Attributes["quantity"].Value)
};
}
// CTOR METHOD
public WalletTransaction(XmlNode node)
{
TransactionDateTime = node.Attributes["transactionDateTime"].Value;
TransactionID = int.Parse(node.Attributes["transactionID"].Value);
Quantity = int.Parse(node.Attributes["quantity"].Value);
}
}
出於一個很大的原因,在這里我首選靜態工廠。 如果在構造函數中引發異常(例如,int.Parse失敗),則實際異常將包裝在Type Initialization Exception中 。 靜態工廠方法不會受到此缺點的影響,並且使調試更容易一些。
您也可以在靜態方法中放棄字段初始值設定項列表,而改為
var wt = new WalletTransaction();
wt.TransactionDateTime = node.Attributes["transactionDateTime"].Value;
//etc
return wt;
這樣做的好處是可以執行更復雜的處理。 即,一個字段可能是可選的,或者僅當另一個字段設置為true時才存在。
為了使用對象初始化器,您的屬性必須具有公共設置器,因此很難使它們不可變。 如果您確實需要對象不可變,我建議您使用構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.