Binding 一般来说不适用于字段。大多数绑定部分基于 ComponentModelPropertyDescriptor
模型,(默认情况下)适用于属性。这可以启用通知、验证等(这些都不适用于字段)。
出于更多我无法解释的原因,公共领域是一个坏主意。它们应该是属性,事实。同样,可变结构是very馊主意。最重要的是,它可以防止意外的数据丢失(通常与可变结构相关)。这应该是一个类:
[DataContract]
public class StatusInfo
{
[DataMember] public int Total {get;set;}
[DataMember] public string Authority {get;set;}
}
现在它会按照您的预期运行。如果你想让它成为一个不可变的struct,这样就可以了(当然,数据绑定只能是单向的):
[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”代理层无论如何都会将其创建为使用者的类(除非您使用程序集共享)。
在回答“为什么使用结构”回复时(“未知(谷歌)”):
如果这是对我的问题的回答,那么它在很多方面都是错误的。一、值类型作为变量通常(首先)在堆栈上分配。如果它们被推到堆上(例如在数组/列表中),则与类的开销没有太大区别 - 一小部分对象头加上引用。结构应该始终是small。具有多个字段的内容将会过大,并且会破坏您的堆栈或由于位块传送而导致速度缓慢。此外,结构应该是不可变的 - 除非你really知道你在做什么。
几乎任何代表对象的东西都应该是不可变的。
如果您正在访问数据库,与进程外和可能通过网络相比,结构与类的速度不是问题。即使它慢一点,与正确处理(即将对象视为对象)相比也没有什么意义。
由于一些指标超过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();
}
}