Konrad Viltersten
Konrad Viltersten

Reputation: 39078

What do I gain by setting the default values in the interface if I always have to set them again in the implementation?

I've created the following interface.

public interface IMineralService
{
  Task<Mineral[]> GetMinerals(int page = 0, int size = Int32.MaxValue);
  Task<Mineral> GetMineral(int id);
}

Its implementation is as follows.

public class MineralService : IMineralService
{
  public async Task<Mineral[]> GetMinerals(int page = 0, int size = Int32.MaxValue)
  {
    Mineral[] data = await Task.FromResult(Minerals);
    return data.Skip(page * size).Take(size).ToArray();
  }

  public async Task<Mineral> GetMineral(int id)
  {
    Mineral[] data = await GetMinerals();
    return data.SingleOrDefault(a => a.Id == id);
  }
}

I don't understand what's the purpose or implication of declaring the default values for the parameters both in the constructor and in the implementation. Skipping the default values doesn't collide with implementing the interface as such, so the following would work. Id est - there's no imposition of the set defaults from the interface onto the implementation.

public interface IMineralService
{
  Task<Mineral[]> GetMinerals(int page = 0, int size = Int32.MaxValue);
}

public class MineralService : IMineralService
{
  public async Task<Mineral[]> GetMinerals(int page, int size) { ... }
}

It also works with the defaults only being declared in the implementation.

public interface IMineralService
{
  Task<Mineral[]> GetMinerals(int page, int size);
}

public class MineralService : IMineralService
{
  public async Task<Mineral[]> GetMinerals(int page = 0, int size = Int32.MaxValue)
}

However, in order to make the second method work with await GetMinerals(), the defaults must be set in the implementation. So what's the point of ever setting the default in the constructor if it must be re-stated in the implementation (if it's used by another call) or isn't needed at all (if there's no other call utilizing the defaults)?

Upvotes: 1

Views: 589

Answers (1)

StriplingWarrior
StriplingWarrior

Reputation: 156504

Setting default values doesn't add any code to the class that the default values are set on, to set those values. Instead, it makes it so any consuming code that calls those methods without providing an explicit value will actually be compiled to pass the specified value.

Because of this, the optionality of these optional parameters is decoupled from the actual implementation details of the method.

That means it's possible for different interfaces that you implement to provide different default values. Or for the interfaces and the class to have different default values. Or for the implementing class to not even specify a default value at all, but have consumers of the interface still be able to call into that class's method without providing an explicit value.

So it's similar to deciding whether a class should implement an interface method explicitly versus implicitly: you need to think about how you expect your class and interface to be used.

  • If you're following a methodology where consuming classes are expected to inject your interface as a service, and never know about the concrete class backing it, then there's no point setting a default value on your implementing class's method signatures.
  • If your interface and class both share certain expectations, and you expect your class to be used directly in some cases and via the interface in other cases, then it's a good idea to declare the same default value in both.
  • If your interface is expected to be used in ways where a different default value makes sense than in the use cases you envision for people calling into your class directly, then you may want to have different default values for each.

Upvotes: 1

Related Questions