簡體   English   中英

需要許多參數時,C#中的對象初始化程序與構造函數

[英]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.

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