Вы можете использовать объект в качестве параметра здесь; который обычно используется в сценариях, где количество параметров может варьироваться в зависимости от используемого вызова.
struct RegistrationInfo
{
public static readonly RegistrationInfo Empty = new RegistrationInfo();
public string Username;
public string CustomerName;
public string Validity;
}
abstract class Base
{
public abstract void Register(RegistrationInfo info);
// If you want to retain the paramaterless call:
public void Register()
{
Register(RegistrationInfo.Empty);
}
}
class Registrar1 : Base
{
public override void Register(RegistrationInfo info)
{
if (info.Username == null) throw new ArgumentNullException("info.Username");
}
}
class Registrar2 : Base
{
public override void Register(RegistrationInfo info)
{
if (info.CustomerName == null) throw new ArgumentNullException("info.CustomerName");
}
}
Это имеет то преимущество, что вам не нужно изменять параметры метода (что нарушает интерфейс) каждый раз, когда добавляется параметр. Использование также становится несколько самодокументированным:
var r = new Registrar1();
r.Register(new RegistrationInfo(){ Username = "JimJoe" });
r.Register(RegistrationInfo.Empty);
Это как освежитель воздуха для такого типа запаха кода, хотя он все еще вонючий; Вы можете сделать его приятнее пахнуть.
Наконец, вы можете сделать сайт-уборщик более чистым, указав в качестве аргумента params
(это имеет небольшие издержки); Честно говоря, хотя это более вонючий, потому что это языковой взлом. Наконец, вы можете улучшить его с помощью дженериков:
class RegistrationInfo
{
}
class RegistrationInfo1 : RegistrationInfo
{
public string Arg;
}
class RegistrationInfo2 : RegistrationInfo
{
public int Arg;
}
interface IBase<in TRegistration>
where TRegistration : RegistrationInfo
{
void Register(TRegistration registration);
}
class Base : IBase<RegistrationInfo>
{
public void Register(RegistrationInfo registration)
{
}
}
class Registrar1 : IBase<RegistrationInfo1>
{
public void Register(RegistrationInfo1 arg)
{
}
}
class Registrar2 : IBase<RegistrationInfo2>
{
public void Register(RegistrationInfo2 arg)
{
}
}