我正在尝试定义一个实现接口的接口和类,如下所示。接口中定义的方法接受一个字符串作为参数,其中方法Execute
的myClass2实现采用不遵循接口定义的2个参数。
这就是问题所在。如何在接口中定义一个方法,该方法接受各种类型的n个参数?
请指教。感谢。
public interface MyInterface
{
void Execute(string a);
}
public class myClass1 : MyInterface
{
public void Execute(string a)
{
Console.WriteLine(a);
}
}
public class myClass2 : MyInterface
{
public void Execute(string a, int b)
{
Console.WriteLine(a);
Console.WriteLine(b.ToString());
}
}
编辑:我正在考虑另一种方法。如果有人能告诉我这是否是一个更好的设计我很感激。
public interface IParameter
{
Type ParameterType { get; set; }
string Name { get; set; }
object Value { get; set; }
}
public interface MyInterface
{
void Execute(Recordset recordSet, List<IParameter> listParams);
}
public class MyClass : MyInterface
{
public void Execute(Recordset recordSet, List<IParameter> listParams)
{
}
}
我正在传递一个IParameter列表,其中包含需要发送的所有必需参数。
答案 0 :(得分:6)
如果接口没有修复参数类型,调用者如何知道如何调用该方法?
你最接近的可能是:
public interface MyInterface
{
void Execute(params object[] args);
}
然后接口的实现必须处理并传入任意数量的参数 - 您无法实现仅处理单个{{ 1}}参数,但如果int
包含除单个args
值之外的任何,它当然可以抛出异常。
编辑:为了清楚起见,这很少是一个好的设计。在某些非常弱的类型场景中,它可能是合适的,但除此之外,通常值得尝试找到更好的东西。
如果您可以提供有关您尝试做的更多信息,我们可以为您提供更多帮助。
答案 1 :(得分:1)
你有充分的理由不能这样做。接口的不同实现意味着可互换使用。您提出的设计违反了这一原则。如果您想要帮助解决冲突,我认为您需要解释是什么导致您进行此设计。
答案 2 :(得分:1)
所以你将界面定义为
public interface MyInterface
{
void Execute(string a);
}
并尝试将其实现为
public void Execute(string a, int b)
{
...
}
这不起作用 - 你宣布一个界面,并尝试定义其他东西。
可能有用的(基于你到目前为止的帖子我无法分辨)是显式接口实现 - 也就是说,你的具体对象可以公开一个Execute(string,int)方法并显式实现你的接口方法。像
这样的东西public class myClass2 : MyInterface
{
public void Execute(string a, int b)
{
...
}
void MyInterface.Execute(string a)
{
...
}
}
那就是说,我强烈建议你重新考虑这个设计。接口的全部意义在于它们为代码的其余部分提供了一个共同的程序化表面 - 在代码气味方面打破了这个合同的尴尬。
答案 3 :(得分:0)
你可以用弱类型的方法做到这一点。例如,您可以定义一个接受对象数组的接口:
public intrface MyInterface
{
void Execute(params object[] args);
}
而且你可以用任何参数调用你的任何具体类:
myClass.Execute("string", 1);
但是在这种情况下,你违反了接口,继承和编译时检查的主要目的。
实现此目的的另一种方法是实现这一目的,将所有参数封装在附加的类层次结构中:
class CommandData
{
public string StringData {get; set;}
}
class ExtendedCommandData : CommandData
{
public int I {get;set;}
}
interface IMyInterface
{
public void Execute(CommandData commandData);
}
class MyClass1 : IMyInterface
{
public void Execute(CommandData commandData);
}
class MyClass2 : IMyInterface
{
// Lets impelment this interface explicitely
void IMyInterface.Execute(CommandData commandData)
{
}
void Execute(ExtendedCommandData extendedData)
{
// now we can access to string and int parameter
}
}
答案 4 :(得分:0)
除了@Jon回答:考虑到你正在实现一个接口,所以你是架构师,只是不要使用一个接口,而是使用带有重载虚函数的简单基类,并且在每个具体类中都以你喜欢的方式对它进行ocerride
修改强> 我的意思是这样的:不是使用接口声明基类,而是使用伪代码!
public class MyCoolBase // a base CLASS and not interface
{
public virtual void Execute(string a)
{
//empty, or NotImplementedException, base on design decision
}
public virtual void Execute(double b)
{
//empty, or NotImplementedException, base on design decision
}
public virtual void Execute(int a, int b)
{
//empty, or NotImplementedException, base on design decision
}
}
public class MyCoolChildOne : MyCoolBase
{
public override void Execute(string a)
{
//concrete implementation
}
}
public class MyCoolChildTwo : MyCoolBase
{
public override void Execute(int a, int b)
{
//concrete implementation
}
}
依旧......
错误:当您在代码
中执行此类操作时MyCoolBase myCoolBase = new MyCoolChildOne ();
myCoolBase...?(); // should be really sure which function you're going to call on this line
良好:您拥有强大的类型管理功能,不再有object[]
个数组,或者您必须覆盖的多个接口的多重继承,而不是这种情况你甚至可以避免它,即使我认为这不是一个好主意。
顺便说一句,就像这里的极客们所说,我不认为你的架构非常可靠,应该有一些其他的解决方案。我们只是试着找出代码和问题的最佳选择,但真正的问题只能知道你。
希望这有帮助。
问候。
答案 5 :(得分:0)
就其价值而言,这可能是泛型的一个很好的用例。
您将所需的最少参数定义为接口的属性,然后在需要更多参数的地方继承。
在基本接口中仅使用1个参数时,看起来很傻,但是当然可以将此概念扩展为更复杂的类型。
public interface MyInterface<T> where T : ParamA
{
void Execute(T paramA);
}
public interface ParamA
{
string ParameterA { get; }
}
public class myClass1 : MyInterface<myClass1.myParamA>
{
public class myParamA : ParamA
{
public string ParameterA { get; set; }
}
public void Execute(myParamA a)
{
Console.WriteLine(a.ParameterA);
}
}
public class myClass2 : MyInterface<myClass2.myParamsAb>
{
public class myParamsAb : ParamA
{
public string ParameterA { get; set; }
public int ParameterB { get; set; }
}
public void Execute(myParamsAb ab)
{
Console.WriteLine(ab.ParameterA);
Console.WriteLine(ab.ParameterB.ToString());
}
}