کار با انواع protobuf

از آنجایی که API گوگل ادز از proto3 به عنوان فرمت پیش‌فرض بارگذاری خود استفاده می‌کند، درک چند قرارداد و نوع Protocol Buffers هنگام کار با کتابخانه کلاینت .NET مهم است.

فیلدهای اختیاری

بسیاری از فیلدها در API گوگل ادز به عنوان optional علامت‌گذاری شده‌اند. این به شما امکان می‌دهد بین مواردی که فیلد دارای مقدار خالی است و مواردی که سرور مقداری برای فیلد برنمی‌گرداند، تمایز قائل شوید. این فیلدها مانند ویژگی‌های معمولی رفتار می‌کنند، با این تفاوت که متدهای اضافی برای پاک کردن فیلد و بررسی تنظیم بودن فیلد نیز ارائه می‌دهند.

برای مثال، فیلد Name شیء Campaign به صورت optional علامت‌گذاری شده است، بنابراین می‌توانید از روش‌های زیر برای کار با این فیلد استفاده کنید:

// Get the name.
string name = campaign.Name;

// Set the name.
campaign.Name = name;

// Check if the campaign object has the name field set.
bool hasName = campaign.HasName();

// Clear the name field. Use this method to exclude the Name field from
// being sent to the server in a subsequent API call.
campaign.ClearName();

// Set the campaign name to an empty string value. This value will be
// sent to the server if you use this object in a subsequent API call.
campaign.Name = "";

// This throws a runtime ArgumentNullException. Use ClearName() instead.
campaign.Name = null;

فیلدهای تکراری

یک آرایه فیلد در API گوگل ادز به صورت یک RepeatedField فقط خواندنی نمایش داده می‌شود.

برای مثال، فیلد url_custom_parameters یک کمپین، یک فیلد تکراری است، بنابراین به صورت یک RepeatedField<CustomParameter> فقط خواندنی در کتابخانه کلاینت .NET نمایش داده می‌شود. RepeatedField<T> رابط IList<T> را پیاده‌سازی می‌کند.

دو روش برای پر کردن یک ویژگی RepeatedField وجود دارد:

روش AddRange

Campaign campaign = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    Status = CampaignStatus.Paused,
};

// Add values to UrlCustomParameters using the AddRange method.
campaign.UrlCustomParameters.AddRange(new CustomParameter[]
{
    new CustomParameter { Key = "season", Value = "christmas" },
    new CustomParameter { Key = "promocode", Value = "NY123" }
});

نحو مقداردهی اولیه مجموعه

// Option 1: Initialize the field directly.
Campaign campaign = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    Status = CampaignStatus.Paused,
    // Directly initialize the field.
    UrlCustomParameters =
    {
        new CustomParameter { Key = "season", Value = "christmas" },
        new CustomParameter { Key = "promocode", Value = "NY123" }
    }
};

// Option 2: Initialize using an intermediate variable.
CustomParameter[] parameters = new CustomParameter[]
{
    new CustomParameter { Key = "season", Value = "christmas" },
    new CustomParameter { Key = "promocode", Value = "NY123" }
};

Campaign campaign1 = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    Status = CampaignStatus.Paused,
    // Initialize from an existing array.
    UrlCustomParameters = { parameters }
};

یکی از فیلدها

برخی از فیلدها در API گوگل ادز به عنوان فیلدهای oneof علامت‌گذاری شده‌اند، به این معنی که فیلد می‌تواند انواع مختلفی را در خود جای دهد اما در یک زمان معین فقط یک مقدار را می‌تواند در خود جای دهد. فیلدهای oneof شبیه به نوع union در زبان برنامه‌نویسی C هستند.

کتابخانه‌ی دات‌نت، فیلدهای oneof را با ارائه‌ی یک ویژگی برای هر نوع مقداری که می‌تواند در یک فیلد oneof نگهداری شود، پیاده‌سازی می‌کند و تمام ویژگی‌ها یک فیلد ذخیره‌سازی مشترک را به‌روزرسانی می‌کنند.

برای مثال، campaign_bidding_strategy کمپین به عنوان فیلد oneof علامت‌گذاری شده است. این کلاس به صورت زیر پیاده‌سازی شده است (کد برای اختصار ساده شده است):

public sealed partial class Campaign : pb::IMessage<Campaign>
{
    object campaignBiddingStrategy_ = null;
    CampaignBiddingStrategyOneofCase campaignBiddingStrategyCase_;

    public ManualCpc ManualCpc
    {
        get
        {
            return campaignBiddingStrategyCase_ ==
                CampaignBiddingStrategyOneofCase.ManualCpc
                ? (ManualCpc)campaignBiddingStrategy_ : null;
        }
        set
        {
            campaignBiddingStrategy_ = value;
            campaignBiddingStrategyCase_ =
                CampaignBiddingStrategyOneofCase.ManualCpc;
        }
    }

    public ManualCpm ManualCpm
    {
        get
        {
            return campaignBiddingStrategyCase_ ==
                CampaignBiddingStrategyOneofCase.ManualCpm
                ? (ManualCpm)campaignBiddingStrategy_ : null;
        }
        set
        {
            campaignBiddingStrategy_ = value;
            campaignBiddingStrategyCase_ =
                CampaignBiddingStrategyOneofCase.ManualCpm;
        }
    }

    public CampaignBiddingStrategyOneofCase CampaignBiddingStrategyCase
    {
        get { return campaignBiddingStrategyCase_; }
    }
}

از آنجایی که oneof ویژگی‌ها فضای ذخیره‌سازی را به اشتراک می‌گذارد، یک تخصیص می‌تواند تخصیص قبلی را بازنویسی کند و منجر به اشکالات نامحسوس شود. برای مثال:

Campaign campaign = new Campaign()
{
    ManualCpc = new ManualCpc(),
    ManualCpm = new ManualCpm()
};

در این حالت، campaign.ManualCpc null است زیرا مقداردهی اولیه campaign.ManualCpm ، مقداردهی اولیه قبلی برای campaign.ManualCpc را بازنویسی می‌کند.

تبدیل به فرمت‌های دیگر

تبدیل به فرمت JSON

شما می‌توانید اشیاء protobuf را با استفاده از Google.Protobuf.JsonFormatter به فرمت JSON و برعکس تبدیل کنید. این قابلیت هنگام ساخت سیستم‌هایی که نیاز به ارتباط با سایر سیستم‌هایی دارند که به فرمت‌های متنی مانند JSON یا XML نیاز دارند، مفید است.

using Google.Protobuf;

GoogleAdsRow row = new GoogleAdsRow()
{
    Campaign = new Campaign()
    {
        Id = 123,
        Name = "Campaign 1",
        ResourceName = ResourceNames.Campaign(1234567890, 123)
    }
};

// Serialize to JSON and back.
string json = JsonFormatter.Default.Format(row);
row = GoogleAdsRow.Parser.ParseJson(json);

تبدیل به بایت

شما می‌توانید با استفاده از Google.Protobuf یک شیء را به بایت تبدیل کرده و برعکس، آن را سریالی کنید. سریالی‌سازی دودویی در مقایسه با فرمت JSON، از نظر حافظه و ذخیره‌سازی کارآمدتر است.

using Google.Protobuf;

GoogleAdsRow row = new GoogleAdsRow()
{
    Campaign = new Campaign()
    {
        Id = 123,
        Name = "Campaign 1",
        ResourceName = ResourceNames.Campaign(1234567890, 123)
    }
};

// Serialize to bytes and back.
byte[] bytes = row.ToByteArray();
row = GoogleAdsRow.Parser.ParseFrom(bytes);