And*_*rko 19 c# struct dto n-tier-architecture
所以,实际上这个问题是我目前的基石.我正在努力重构我的个人项目,尝试提高性能,优化内存使用,使代码简单明了.我有一个不同的应用程序层(实际上,DAL,BLL,ServiceAgent是WCF服务).我使用实体/模型/ DTO在这些层之间传递数据,这是无状态的(根本没有任何逻辑).目前这是一个像这样的对象
public class Person
{
public ComplexId Id { get; set; }
public string Name { get; set; }
// ...
}
Run Code Online (Sandbox Code Playgroud)
我曾经使用这种方法,它就像是"最佳实践",是吗?这是存储传输数据的最佳方式吗?如果我为这样的结构更改它会怎么样:
public struct Peson
{
public ComplexIdentifier ComplexId;
public string Name;
}
public struct ComplexIdentifier
{
public int LocalId;
public int GlobalId;
}
Run Code Online (Sandbox Code Playgroud)
从性能/内存使用角度来看,这是更好的方法吗?或者也许有某种陷阱这样做?
Ada*_*rth 17
对于标准DTO实体,您将希望坚持使用该类.
A struct具有比类更有限的潜在用例范围.当struct类型变得太大时,也存在效率问题(不要忘记,它们是值类型并在传递时被复制),如MSDN关于值类型的指南中所述.当你开始通过属性暴露类型时,或者在引用接口时意外地将它包装起来,或者使它们变得可变时,更不用说很多陷阱struct......
我不是说不能使用 struct时,它是相关的,但我很很少能找到自己需要使用struct在我们的主要桌面应用程序类型-这是分层的,并设有DTO类型.
struct对class.您需要使用dotTrace或ANTS等分析工具才能找到热点并从那里开始.性能问题并非微不足道,好的工具通常是答案的开始.
从性能/内存使用的角度来看,这会是更好的方法吗?
不。结构是值类型,因此它们是按值复制的。这意味着您将始终复制完整的对象,而不是仅复制引用。如果有的话,它可能会稍微慢一些并使用更多内存(因为对象会重复)。
不应该这样做的另一个原因:应始终避免使用可变结构,因为如果您不小心,它们可能会导致意外行为。
数据传输对象的两个最佳选择通常应该是深度不可变的类对象,或者是具有适合用作数据传输对象的类型的公开字段的结构.其他类型的结构有时也可以使用,但是暴露场结构是迄今为止最简单的结构,简单是一种很好的美德.
可变结构是邪恶的概念可以追溯到一些早期的C#编译器
SomeReadonlyStruct.SomeProperty = 5;
将由编译器静默转换为:
var temp = SomeReadonlyStruct; temp.SomeProperty = 5;
隐藏readonly属性后面的struct字段是为了确保前一个语句拒绝编译而不是产生损坏的代码.由于较新的编译器将拒绝改变只读结构的可写字段,因此不再需要将字段包装在只读属性中.
与其他类型的数据传输对象相比,具有暴露字段的结构具有巨大的优势:每个具有适合于数据传输的类型的公开字段的结构,除了构造函数之外没有其他成员,其行为方式相同,没有任何意外.从未使用过结构体的人可能会对他们不像课程这样的事实感到有些惊讶,但是了解任何这样的结构如何工作的人将会理解它们是如何工作的.
请考虑以下代码:
customerPhone = someDataSource.GetPhoneNumber(customerID); customerPhone.Extention = "5309"
有些人不喜欢这样一个事实:如果customerPhone是一个暴露字段结构,设置Extension属性不会影响信息someDataSource.虽然写一个struct字段不会更新任何其他东西,但这是一个比customerPhone一个可变类类型存在的情况要好得多的情况.任何了解customerPhone暴露字段结构类型的人都会知道对其成员的更改不会影响其他任何内容.相反,如果customerPhone是可变类类型,则上述代码可能会someDataSource通过更改与之关联的电话号码进行更新customerID.或者它可能不会.或者,如果一个电话号码与两个customerID值相关联,则上述代码可能会更改这两个值.可能需要研究的代码量以确定上述代码可能具有的确切影响和副作用将是非常大的.更糟糕的是,可能很难确定一个人没有遗漏任何东西.
肯定有一些地方传递类对象引用比传递结构更有效.还有一些情况,可变类对象可以成为类中有用的数据持有者.但是,一些通用包装器可以在一个可变或不可变的类中包装一个结构,并在这些类的类之间交换信息.
interface IReadableHolder<T> { T Value {get;} }
class MutableHolder<T> : IReadableHolder<T>
{
public T Value;
IReadableHolder.Value {get {return Value;} }
public MutableHolder(T newValue) { Value = newValue; }
public MutableHolder(IReadableHolder<T> it) { Value = it.Value; }
}
class ImmutableHolder<T> : IReadableHolder<T>
{
T _Value;
public Value {get {return _Value;} }
public ImmutableHolder(T newValue) { _Value = newValue; }
}
没有可变的结构,这样的结构会更加尴尬.
| 归档时间: |
|
| 查看次数: |
5562 次 |
| 最近记录: |