我有一个我正在编写的方法,它正在调用其中的另一个重载方法。我只想写一个外部方法,因为外部方法的参数被传递给内部方法。有没有办法做到这一点?
我尝试使用泛型,但我对此知之甚少,所以它不起作用:
public void OuterMethod<T>(T parameter)
{
InnerMethod(parameter); // InnerMethod accepts an int or a string
}
我知道我可以这样做:
public void OuterMethod(string parameter)
{
InnerMethod(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethod(parameter);
}
但我宁愿以正确的方式做到这一点,而不是复制/粘贴代码。实现这一目标的最佳方法是什么?
答案 0 :(得分:4)
您可以在C ++中执行此操作,但不能在C#中执行此操作(除非内部方法也可以是通用的而不是重载的。)
或者(如果您不回答“否”),您可以在类型上执行运行时切换,例如......
public void OuterMethod(object parameter)
{
if (parameter is int)
InnerMethod((int)parameter);
else if (parameter is string)
InnerMethod((string)parameter);
else
throw new SomeKindOfException();
}
...但显然这是一个运行时,而不是编译时检查。
但我宁愿以正确的方式做到这一点,而不是复制/粘贴代码。
您也可以编写软件来编写外部方法(例如使用System.CodeDom类)而不是手工编写它们,但这可能比它的价值更麻烦。
答案 1 :(得分:2)
就像其他人所说的那样,你无法真正做到你想要做的事情,你在问题中提出的选择是最好的选择。
如果使用泛型,则实际上必须转换该值。否则,你可以通过接受一个像ChrisW建议的对象来预测。
public void OuterMethod<T>(T parameter)
{
T temp = parameter;
if (temp is string )
InnerMethod(Convert.ToString(temp));
if (temp is int)
InnerMethod(Convert.ToInt32(temp));// InnerMethod accepts an int or a string
}
以下是泛型概述的链接:http://msdn.microsoft.com/en-us/library/ms172193.aspx
答案 2 :(得分:1)
根据您的描述,这似乎过度优化。
怎么样:
public void OuterMethod(string parameter)
{
InnerMethod(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethod(parameter**.ToString()**);
}
答案 3 :(得分:1)
您可以使用dynamic
类型将重载决策推迟到运行时。
public void OuterMethod(dynamic parameter)
{
InnerMethod(parameter);
}
public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }
警告 Expressions of type dynamic are not resolved or type checked by the compiler.并且可能会有性能下降。
答案 4 :(得分:0)
如果OuterMethod总是调用InnerMethod,而InnerMethod只接受int或string,那么OuterMethod&lt; T&gt;没有任何意义。
如果只有 的区别是调用InnerMethod(int)而另一个调用InnerMethod(string),你可以这样做:
public void OuterMethod(string parameter)
{
InnerMethodA(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethodA(parameter);
}
private void InnerMethodA(object parameter)
{
// Whatever other implementation stuff goes here
if (parameter is string)
{
InnerMethodB((string) parameter);
}
else if (parameter is int)
{
InnerMethodB((string) parameter);
}
else
{
throw new ArgumentException(...);
}
}
private void InnerMethodB(string parameter)
{
// ...
}
private void InnerMethodB(int parameter)
{
// ...
}
答案 5 :(得分:0)
好的我有类似的情况,它是我的业务逻辑中的一种访问控制方法。
有一个保存功能可以应用于我的任何持久层对象。
所以看起来像这样
public static Save<T>(AccessControl.User user,T entity) where T:PersistanceLayerBaseClass
{
if(CanWrite(user, entity))
{
entity.save();
}
else
{
throw new Exception("Cannot Save");
}
}
我如何在访问控制方面为某些实体设置一些自定义代码,所以我编写了以下内容,它寻找一种更适合使用System.Reflection的问题的方法,“这个实体可以由这个用户编写吗?”
public static Boolean CanWrite<T>(AccessControl.User user, T entity) where T : PersistanceLayerBaseClass
{
int? clubId = null;
MethodInfo methodInfo = entity.GetType().GetMethod("CanWrite", new Type[] { typeof(AccessControl.User), entity.GetType() });
if(methodInfo != null)
{
return (Boolean)methodInfo.Invoke(null, new object[] { user, entity }) ;
}
else
{
//generic answer
}
return HasRole(user.UserID, "Administrator") || (clubId.HasValue && user.MemberObject.ClubId == clubId.Value && HasRole(user.UserID, "AdministerClub"));
}
现在每次添加或删除方法时,我只需要在一个地方添加或删除它