基础数据,运行时数据,XML格式的网络数据

时间:2011-06-21 13:54:46

标签: c# xml xsd

假设我在一个可以通过网络播放的游戏中有一个Car类。我们拥有的基本属性永远不会像model和engineSize那样改变,每个游戏都是相同的。我们有运行时属性,例如当前位置和当前速度,我们可能希望保存当前游戏并稍后重新加载。最后,我们有必须通过网络传输给其他玩家的数据 - 可能在这种情况下,位置和速度再次提高,但让我们说速度和距离远离你。

所以我们有一个看起来类似的类(忽略确切的语法或对身份的争论):

public Car
{
    public string Model; /* Base data */
    public int EngineSize; /* Base data */
    public PointF Location; /* Runtime data */
    public double Speed; /* Runtime and network data */
    public double distanceAwayFromYou; /* Network data */
}

现在,我可以编写一个模式来为基础数据,运行时数据或网络数据创建可序列化的部分类(例如,使用xsd.exe)。但是在这里我有一个单独的类,其中包含三个XML数据子集:

基础数据:

<Car>
    <Model>Honda</Model>
    <EngineSize>2999</EngineSize>
</Car>

运行时数据:

<Car>
    <Location><X>10</X><Y>20</Y></Location>
    <Speed>60.4</Speed>
</Car>

网络数据:

<Car>
    <Speed>60.4</Speed>
    <DistanceFromYou>45.67</DistanceFromYou>
</Car>

我之前使用自定义属性和反射解决了这个问题;然而,它并不漂亮 - 据我所知 - 无法自动对模式进行验证。有更简单的方法,或者你会怎么做?

感谢。

1 个答案:

答案 0 :(得分:0)

在这种情况下,试试这个:

  1. 制作IRuntime界面:

    public interface IRuntime
    {       
        PointF Location
        {
            get;
            set;
        }
    
        double Speed
        {
            get;
            set;
        }
    }
    
  2. 制作INetwork接口:

    public interface INetwork
    {
        double Speed
        {
            get;
            set;
        }
    
        double DistanceAwayFromYou
        {
            get;
            set;
        }
    }
    
  3. 创建一个继承自这些接口的类:

    class Car : IRuntime, INetwork
    {
        private string _model = string.Empty;
        private int _engineSize = 0;
        private PointF _location = new PointF();
        private double _distanceAwayFromYou = 0; 
        private double _runtimeSpeed = 0;
        private double _networkSpeed = 0;
    
        public string Model
        {
            get
            {
                return _model;
            }
            set
            {
                if (_model != value)
                {
                    _model = value;
                }
            }
        }
    
        public int EngineSize
        {
            get
            {
                return _engineSize;
            }
            set
            {
                if (_engineSize != value)
                {
                    _engineSize = value;
                }
            }
        }
    
        PointF IRuntime.Location
        {
            get
            {
                return _location;
            }
            set
            {
                if (_location != value)
                {
                    _location = value;
                }
            }
        }
    
    
        double INetwork.DistanceAwayFromYou
        {
            get
            {
                return _distanceAwayFromYou;
            }
            set
            {
                if (_distanceAwayFromYou != value)
                {
                    _distanceAwayFromYou = value;
                }
            }
        }
    
    
        double IRuntime.Speed
        {
            get
            {
                return _runtimeSpeed;
            }
            set
            {
                if (_runtimeSpeed != value)
                {
                    _runtimeSpeed = value;
                }
            }
        }
    
        double INetwork.Speed
        {
            get
            {
                return _networkSpeed;
            }
            set
            {
                if (_networkSpeed != value)
                {
                    _networkSpeed = value;
                }
            }
        }
    }
    
  4. 然后在您的消费代码中,您可以执行以下操作:

        Car myCar = new Car();
        //Note that you are able to set only two properties using an instance of Car i.e. Model and EngineSize
        myCar.Model = "test";
        myCar.EngineSize = 9; 
    

    如果您愿意,可以保存上述内容。但是,如果要保存运行时数据,请执行以下操作:

        IRuntime runtimeCar = (IRuntime)myCar;
        //Note that now you are able to set properties related to runtime data. This is upcasting.
        runtimeCar.Location = new PointF(20, 30);
        runtimeCar.Speed = 50;        
    

    对于与网络相关的数据,您可以执行以下操作:

        INetwork networkCar = (INetwork)myCar;
        //Now you are only able to set properties related to network data using upcast.
        networkCar.Speed = 70;
        networkCar.DistanceAwayFromYou = 50;
    

    希望这有帮助。