为什么在类属性中没有复杂的逻辑被认为是最佳实践?

时间:2009-01-28 16:26:53

标签: c# properties

这样的代码有什么缺点:

public class Class1
{
   public object Property1
   {

        set 
        {
             // Check some invariant , and null

             // throw exceptions if not satisfied

             // do some more complex logic

             //return value 
        }

   }
}

7 个答案:

答案 0 :(得分:11)

如果你做了过多的逻辑,需要花费很长一段时间,和/或副作用不能从属性的设置中逻辑流动,那么你将会有一个非常复杂的课程设计。

传统上,方法用于表示正在执行具有后果的操作,而不是属性。虽然你肯定可以拥有逻辑,但是过多可能会给你错误的印象,即你要做什么,分配一个值,而不是执行一个操作。

最后,这完全取决于“做一些更复杂的逻辑”的含义。

答案 1 :(得分:4)

很难回答这个问题,因为“复杂的逻辑”非常模糊。

我发现在设置属性时基本的健全性检查没有问题,当一个属性发生变化时,需要对对象进行某种处理是很常见的。

现在,如果通过“复杂的逻辑”,你的意思是做一些像疯狂的数据库访问或创建网络连接去做某事然后是的,这将是坏事。

答案 2 :(得分:2)

如果你看到一个属性,你会认为它的行为就像一个字段,即你可以一遍又一遍地检索它的值:

if(obj.Prop.Equals(otherObj.Prop))
{
    Console.WriteLine(obj.Prop);
    Log.CreateEntry(obj.Prop);
}

Prop作为方法实施。用户怀疑昂贵的计算,并且可能会将结果复制到局部变量中并改为使用它。

属性绝不能更改对象。 如果属性的值未更改,则应始终返回相同的对象。特别是如果对象的创建很昂贵(比如在每次调用时返回一个新的StreamReader)

答案 3 :(得分:2)

属性应力求无副作用。 如果副作用对于类的消费者是不可见的(一个字符串的懒惰创建然后不会改变)那么这不是一个问题。 默认情况下,调试器倾向于显示(从而评估)属性。如果它们有副作用,这可能会引起相当大的痛苦。

如果提供的值非法,则从设定者处投掷通常是可以的。从吸气剂中投掷通常被认为很差。

这些一如既往的经验法则规定他们不会被遵循。一个很好的例子是通过Linq to SQL生成的类型的属性。如果您对子属性进行了延迟查找,那么对它进行评估确实会触发数据库读取。这是偏移但是结果对象的易用性,可读性和一致性 - 它是平衡竞争规则之一。

警惕必须或永远不会说的规则。有时这种性质的规则存在,并且是合理的,但它们实际上并不常见。

答案 4 :(得分:1)

预计属性执行起来很便宜。如果属性的值不需要保存在变量中以避免昂贵的属性代码执行,则代码看起来更整洁。

设置它们也是如此,不期望分配值会调用一些昂贵的操作。

答案 5 :(得分:1)

为了清晰起见,代码业务逻辑应该与属性设置器分开。简单的健全检查可以而且应该经常在酒店内进行。但是任何特定于应用程序的东西,或者不是立即隐含在类型中的东西都应该被抽象掉。 对于最佳OO实践您可能希望任何仅适用于该对象的逻辑成为该对象的一部分,并且任何与您对该对象进行交易相关的复杂逻辑应该位于处理该对象的代码部分。

答案 6 :(得分:0)

为了使代码易于理解,最好能get完全具有set的内容。

除了“一些复杂的逻辑”,我们现在看不到,这段代码看起来并不是一团糟。