3

我有一个正在编写的方法,它在其中调用另一个重载方法。我只想写一个外部方法,因为外部方法的参数被传递给内部方法。有没有办法做到这一点?

我尝试使用泛型,但我对此知之甚少,因此它不起作用:

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);
}

但我宁愿以正确的方式做到这一点,而不是复制/粘贴代码。实现这一目标的最佳方法是什么?

4

6 回答 6

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 类)而不是手动编写它们,但这可能比它的价值更麻烦。

于 2009-01-07T23:44:05.387 回答
2

就像其他人说的那样,您不能真正做您想做的事情,而您在问题中陈述的选项是最好的选择。

如果您使用泛型,您实际上必须转换该值。否则,您可以通过接受 ChrisW 建议的 Object 来沮丧。

 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

于 2009-01-08T00:06:34.700 回答
1

根据您的描述,这似乎是过度优化。

怎么样:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter**.ToString()**);
}
于 2009-01-08T00:57:47.390 回答
1

您可以使用dynamic类型将重载决议推迟到运行时。

public void OuterMethod(dynamic parameter)
{
    InnerMethod(parameter);
}

public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }

警告 动态类型的表达式不会被编译器解析或类型检查。并且可能还会有性能损失。

于 2014-12-01T17:31:15.103 回答
0

如果 OuterMethod 总是调用 InnerMethod,而 InnerMethod 只接受一个 int 或 string,那么 OuterMethod<T> 没有任何意义。

如果唯一的区别是一个调用 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)
{
    // ...
}
于 2009-01-07T23:59:31.143 回答
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"));
        }

现在每次我添加或删除一个方法时,我只需要在一个地方添加或删除它

于 2009-02-17T12:33:21.173 回答