我有一个带有Bar方法的IFoo接口,带有一个字符串参数。该接口实现了一个返回常量值的实现,而根本不使用任何参数。另一个使用参数。
如何避免使用这个无用的参数? 这是一个虚拟的实现
public interface IFoo
{
string Bar(string parameter);
}
public class Foo : IFoo
{
public string Bar(string parameter)
{
return string.Format("{0}Fooooooo", parameter);
}
}
public class ConstantFoo : IFoo
{
public string Bar(string parameter)
{
return "Baaaaaaar";
}
}
public class Caller
{
private readonly IFoo _foo;
private readonly IFoo _constFoo;
public Caller()
{
_foo = new Foo();
_constFoo = new ConstantFoo();
}
public void DummyUsage()
{
string arg = "Wololo";
Console.WriteLine(_foo.Bar(arg));
Console.WriteLine(_constFoo.Bar(arg));
}
}
答案 0 :(得分:1)
类实现的功能或属性的签名必须始终与各自的接口相同。 如果您自己可以控制接口,则可以在接口和实现类中同时更改签名。
public interface IFoo
{
string Bar();
}
public class Foo : IFoo
{
public string Bar()
{
return "Fooooooo";
}
}
如果这不是您想要的,则可能表明您的继承模型没有很好地定义。
答案 1 :(得分:0)
在接口IFoo中声明一个没有任何参数的附加方法Bar()
public interface IFoo
{
string Bar(string parameter);
string Bar();
}
public class Foo : IFoo
{
public string Bar(string parameter)
{
return string.Format("{0}Fooooooo", parameter);
}
public string Bar()
{
return string.Empty;
}
}
public class ConstantFoo : IFoo
{
public string Bar(string parameter)
{
return string.Empty;
}
public string Bar()
{
return "Baaaaaaar";
}
}
public class Caller
{
private readonly IFoo _foo;
private readonly IFoo _constFoo;
public Caller()
{
_foo = new Foo();
_constFoo = new ConstantFoo();
}
public void DummyUsage()
{
string arg = "Wololo";
Console.WriteLine(_foo.Bar(arg));
Console.WriteLine(_constFoo.Bar());
}
}
答案 2 :(得分:0)
您的示例有一个事实。.作为类的生成者,您知道实现细节,您确切地知道IFoo
的实例类型是
public class Caller
{
private readonly IFoo _foo;
private readonly IFoo _constFoo;
public Caller()
{
_foo = new Foo(); // => here is exact instance type
_constFoo = new ConstantFoo(); // => here is exact instance type
}
public void DummyUsage()
{
string arg = "Wololo";
Console.WriteLine(_foo.Bar(arg)); // -> here you know that you need parameterarg
Console.WriteLine(_constFoo.Bar(arg)); // -> here you know that you do not need parameter arg
}
现在考虑一下:
public class Caller
{
private readonly IEnumerable<IFoo> _fooServices;
public Caller(IEnumerable<IFoo> fooServices)
{
_fooServices = fooServices;
}
public void DummyUsage()
{
string arg = "Wololo";
foreach(IFoo fooService in _fooServices)
{
Console.WriteLine(fooService.Bar(arg)); //==> you do not know what type of foo it is if it require internally argument or not .. But you have to pass it to satisfy contract defined by IFoo interface
}
}
现在另一个
假设您有2个界面:
interface IFoo
{
void Bar();
}
interface IParametrizedFoo
{
void Bar(string parameter);
}
那么您就可以实施
public class Foo : IParametrizedFoo
{
public string Bar(string parameter)
{
return string.Format("{0}Fooooooo", parameter);
}
}
public class ConstantFoo : IFoo, IParametrizedFoo
{
public string Bar()
{
return "Baaaaaaar";
}
string IParametrizedFoo.Bar(string parameter)
{
Bar();
}
}
然后使用
public class Caller
{
private readonly IParametrizedFoo _parametrizedFoo;
private readonly IFoo _foo;
public Caller(IParametrizedFoo parametrizedFoo, IFoo foo)
{
_parametrizedFoo= parametrizedFoo;
_foo= foo;
}
public void DummyUsage()
{
string arg = "Wololo";
Console.WriteLine(parametrizedFoo.Bar(arg));
Console.WriteLine(_foo.Bar());
}
但是我仍然不认为这是最好的设计