一般来说,绑定不适用于字段。大部分绑定都基于ComponentModel的PropertyDescriptor模型,在默认情况下使用属性。这可以启用通知、验证等功能(其中没有一个功能适用于字段)。
有更多原因我无法解释,公共字段是个坏主意。它们应该是属性。同样,可变结构体是个非常糟糕的想法。至少,这可以防止意外数据丢失(通常与可变结构体相关)。建议将其定义为类:
[DataContract]
public class StatusInfo
{
[DataMember] public int Total {get;set;}
[DataMember] public string Authority {get;set;}
}
现在它将按照您认为的方式运作。如果您希望它成为一个不可变结构体,那也可以(但数据绑定只能是单向的):
[DataContract]
public struct StatusInfo
{
[DataMember] public int Total {get;private set;}
[DataMember] public string Authority {get;private set;}
public StatusInfo(int total, string authority) : this() {
Total = total;
Authority = authority;
}
}
然而,我首先要问的是为什么这首先是一个结构体。在.NET语言中编写结构体非常罕见。请记住,WCF的“mex”代理层将在消费者端将其创建为类(除非使用程序集共享)。
回答“为什么使用结构体”的回复(“未知(Google)”):
如果那是对我的问题的回复,则在许多方面都是错误的。 首先,“值类型作为变量”通常分配在堆栈上(首先)。 如果将它们推入堆(例如在数组/列表中),则与类的开销相差不大-一个小的对象标题加上引用。 结构体应始终很小。带有多个字段的结构体将过大,会损坏您的堆栈,或者只是因blitting而导致缓慢。 此外,结构体应该是不可变的-除非您确实知道自己在做什么。
几乎任何表示对象的东西都应该是不可变的。
如果您正在访问数据库,则结构体与类的速度相比,与跨进程甚至可能通过网络的速度相比,都不是问题。即使稍微慢一点,也意味着与正确处理点(即将对象视为对象)相比毫无意义。
对于超过1M个对象的某些度量:
struct/field: 50ms
class/property: 229ms
根据以下结果(速度差异在对象分配中,而不是字段与属性之间)。因此大约慢了5倍,但仍然非常快。由于这不会成为您的瓶颈,请勿过早优化!
using System;
using System.Collections.Generic;
using System.Diagnostics;
struct MyStruct
{
public int Id;
public string Name;
public DateTime DateOfBirth;
public string Comment;
}
class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public string Comment { get; set; }
}
static class Program
{
static void Main()
{
DateTime dob = DateTime.Today;
const int SIZE = 1000000;
Stopwatch watch = Stopwatch.StartNew();
List<MyStruct> s = new List<MyStruct>(SIZE);
for (int i = 0; i < SIZE; i++)
{
s.Add(new MyStruct { Comment = "abc", DateOfBirth = dob,
Id = 123, Name = "def" });
}
watch.Stop();
Console.WriteLine("struct/field: "
+ watch.ElapsedMilliseconds + "ms");
watch = Stopwatch.StartNew();
List<MyClass> c = new List<MyClass>(SIZE);
for (int i = 0; i < SIZE; i++)
{
c.Add(new MyClass { Comment = "abc", DateOfBirth = dob,
Id = 123, Name = "def" });
}
watch.Stop();
Console.WriteLine("class/property: "
+ watch.ElapsedMilliseconds + "ms");
Console.ReadLine();
}
}