Home > Software engineering >  Set a getter using => C#
Set a getter using => C#

Time:12-16

Can I Simplify this:

public override Valor Nome
{
    get
    {
        return new Valor
        {
            ValorEntrada = "agência centro"
        };
    }
}

To something like this:

public override Valor Test => Valor.ValorEntrada = "Value";

Valor has a property called ValorEntrada and this receives a string.

CodePudding user response:

Yes. But you still need the new operator with an object-initializer...

public override Valor Test => new Valor { ValorEntrada = "Value" };

...however that is a bad design.

  • Assuming that your Valor type is a class rather than a struct, then returning new Valor in a property-getter means potentially unnecessary managed-heap object allocations.

    • While allocations are "cheap" (I wouldn't personally say that), the cost of GC isn't.
    • In .NET, property-getters should always be both side-effect-free and always safe to use regardless of the state of the containing object. While there's nothing in the example code which seems to have side-effects, it does break caller's expectations about object identity.
    • For example, this is how the property will behave, and I'd argue this violates expectations:
      Foo foo = new Foo();
      Valor v1 = foo.Test;
      Valor v2 = foo.Test;
      Console.WriteLine( Object.ReferenceEquals( v1, v2 ) ); // "False"
      
  • The fact you're using an object-initializer to set what looks like a required property instead of passing the "Value" string via a constructor parameter suggests that your Valor class is mutable.

    • Which is bad, given the points above.

    • Because it means this will happen:

      Foo foo = new Foo();
      foo.Test.ValorEntrada = "x";
      Console.WriteLine( foo.Test.ValorEntrada ); // "Value" not "x"
      

Better alternatives:

A better solution depends on what exactly your Valor class represents, and what the Test property is meant to do.

  • If the parent class is intended as a factory then you should use a method, not a property, that way you're not breaking any assumptions or implied contracts imposed by using a property:

    public Valor CreateNewValor() => new Valor { ValorEntrada = "Value" };
    
  • If the Valor type should be immutable then you should populate it using a constructor and store it in a readonly field (or readonly auto-property). It will most likely also be appropriate to use a static field as there's no point having multiple copies of identical immutable objects:

    private static readonly Valor _instance = new Valor( valorEntrada: "Value" );
    
    public override Valor Nome => _instance;
    
  • Related