System.Runtime.Serialization如何更新只读属性? [英] How does System.Runtime.Serialization update read-only properties?

查看:51
本文介绍了System.Runtime.Serialization如何更新只读属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个只读属性的类,我只想在构造函数时创建,例如: -



If I have a class with read-only properties that I only want to be created at constructor time e.g.:-

Imports System.Runtime.Serialization

''' <summary>
''' An event to indicate that an FX rate was priced between two currencies
''' </summary>
<DataContract()>
Public Class FXRatePricedEvent
    Inherits AggregateIdentity.CurrencyExchangeAggregateIdentity
    Implements IEvent(Of IAggregateIdentity)

    <DataMember(Name:="Rate")>
    ReadOnly m_rate As Decimal
    <DataMember(Name:="PriceDate")>
    ReadOnly m_pricedate As Date
    <DataMember(Name:="IsDerived")>
    ReadOnly m_derived As Boolean


    ''' <summary>
    ''' The conversion rate between source and target currencies
    ''' </summary>
    ReadOnly Property Rate As Decimal
        Get
            Return m_rate
        End Get
    End Property

    ''' <summary>
    ''' The date/time the FX rate was priced
    ''' </summary>
    ReadOnly Property PriceDate As Date
        Get
            Return m_pricedate
        End Get
    End Property

    ''' <summary>
    ''' Is this rate derived from triangulation or reversal of a priced rate
    ''' </summary>
    ''' <remarks>
    ''' For example a derived GBPJPY can exist s if a priced GBPUSD and USDJPY exist
    ''' </remarks>
    ReadOnly Property IsDerived As Boolean
        Get
            Return m_derived
        End Get
    End Property

    Public Sub New(ByVal currencyFrom As AggregateIdentity.CurrencyAggregateIdentity.ISO_3Digit_Currency,
                   ByVal currencyTo As AggregateIdentity.CurrencyAggregateIdentity.ISO_3Digit_Currency,
                   ByVal fxRate As Decimal,
                   ByVal rateDate As Date,
                   ByVal derived As Boolean)
        ' Set the FX rate aggregate identifier
        MyBase.New(currencyFrom, currencyTo)
        ' and set the other properties
        m_rate = fxRate
        m_pricedate = rateDate
        m_derived = derived
    End Sub

End Class





然后System.Runtime.Serialization可以将此序列化到XML或从XML序列化,没有任何问题。但是我想做一些类似的东西,但是要做一个键值对字典....我的尝试要做的就是打砖墙,除非这个类有一个没有参数的构造函数。



任何想法我(或他们)如何解决这个问题?



Then System.Runtime.Serialization can serialise this to/from XML with no problem. However I want to do something similar but to a key-value pair dictionary....my attempts so to do hit a brick wall unless the class has a constructor with no parameters.

Any ideas how I (or they) get around this?

推荐答案

使用BinaryWriter和BinaryReader保存字典的示例< string,List< string> ;>:
Example of using BinaryWriter, and BinaryReader to save a Dictionary<string,List<string>>:
// required
using System.IO;

private Dictionary<string,List<string>> testDict = new Dictionary<string,List<string>>();

private string appPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"/dctStringString.bin";

private int itemsToCreate = 100000;

private int subListLength = 10;

private void btnTestDictionary_Click(object sender, EventArgs e)
{
    List<string> valueList;

    for (int i = 0; i < itemsToCreate; i++)
    {
        valueList = new List<string>();

        for (int j = 0; j < subListLength; j++)
        {
            valueList.Add(j.ToString());
        }

        testDict.Add(i.ToString(), valueList);
    }

    // serialize
    dctSerialize(testDict, appPath);

    // deserialize
    Dictionary<string,List<string>> deSerializedDict = dctDeserialize(appPath);
}

public void dctSerialize(Dictionary<string,List<string>> dctToWrite, string appPath)
{
    using (var writer = new BinaryWriter(File.Create(appPath)))
    {
        writer.Write(dctToWrite.Count);

        writer.Write(subListLength);

        foreach (var kvp in dctToWrite)
        {
            writer.Write(kvp.Key);
            for (int i = 0; i < subListLength; i++)
            {
                writer.Write(kvp.Value[i]);
            }
        }
        writer.Flush();
    }
}

public Dictionary<string,List<string>> dctDeserialize(string appPath)
{
    using (var reader = new BinaryReader(File.OpenRead(appPath)))
    {
        int itemsToRead = reader.ReadInt32();

        int subListLength = reader.ReadInt32();

        var dctToRead = new Dictionary<string,List<string>>(itemsToRead);

        for (int n = 0; n < itemsToRead; n++)
        {
            string key = reader.ReadString();
            
            List<string> value = new List<string>();

            for (int i = 0; i < subListLength; i++)
            {
                value.Add(reader.ReadString());
            }

            dctToRead.Add(key, value);
        }

        return dctToRead;
    }
}

此测试生成一个文件,其中包含百万+2个整数,大小约为2.46mb;如果您压缩文件,可以将其降低到大约255k。使用标准设置压缩WinRar会产生70k以下的文件。



这是我有一天要完成的事情列表,并使其更加通用。 做一些事情,比如决定是写入文件,还是记忆,参数。



如你所见,如果你开始将泛型类型作为键或值然后你必须做一些扭曲;也许真正的泛型类型大师可以找到解决方法吗?



我用它来提高速度,并根据需要进行调整。 br />


代码是根据对时序的讨论和这里显示的技术进行调整的:[ ^ ];并且,其他来源的内存已经足够擦除了:)



免责声明:如果您使用此代码并导致饥荒,洪水,电网故障,核熔化-down,瘟疫流行等等,请不要让我知道,但如果你发现错误,或者看到更好的实施方式:我全都听见了!

This test generates a file with a million + 2 integers in it of about 2.46mb in size; if you zip the file, you can get it down to about 255k. Compressed with WinRar using standard settings yields a file under 70k.

It's on my list of things to do some day to polish this up and make it more "general purpose." Do things like making whether to write to a file, or memory, a parameter.

As you can see, if you start having generic Types as either Keys or Values in the Dictionary then you have to do some contortions; perhaps a real generic-type-master could find a way around that ?

I use this for speed, adapting it as necessary.

The code was adapted based on the discussion of timing, and techniques shown here: [^]; and, other sources that memory has been kind enough to erase :)

Disclaimer: If you use this code and cause famine, flood, power-grid failure, nuclear melt-down, plague epidemics, etc., please don't let me know, but if you find bugs, or see a better way to implement: I'm all ears !


你好再来一次,



我可以序列化这个(抱歉C# - 我的VB有点生锈......),那么你的情况会有什么不同?



Hi again,

I can serialize this (sorry C# - my VB is a bit rusty...), so what is different in your case?

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;

namespace SerializeDictionary
{
    [DataContract]
    class Data
    {
        [DataMember]
        public string Value;
    }

    [DataContract]
    class Content
    {
        [DataMember(Name = "Dictionary")]
        readonly Dictionary<int, Data> m_dict = new Dictionary<int, Data>();

        public Content()
        {
            m_dict.Add(0, new Data { Value = "Data1" });
            m_dict.Add(1, new Data { Value = "Data3" });
            m_dict.Add(2, new Data { Value = "Data4" });
        }
    }

    static class Program
    {
        /// <summary>
        /// Der Haupteinstiegspunkt für die Anwendung.
        /// </summary>
        [STAThread]
        static void Main()
        {
            var content = new Content();
            DataContractSerializer serializer = new DataContractSerializer(typeof(Content));
            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, content);
                ms.Position = 0;
                var readback = serializer.ReadObject(ms);
            }

            Console.ReadKey();
        }
    }
}


这篇关于System.Runtime.Serialization如何更新只读属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆