具有不同参数类型组合的方法

时间:2016-05-06 14:32:39

标签: c#

我想知道是否可以编写一个可以采用不同参数类型组合的C#方法。

例如,此方法将四个重载方法合并为一个。

public static void MyMethod( (JObject or File) jsonOne, (JObject or File) jsonTwo) {}

3 个答案:

答案 0 :(得分:6)

不,你不能创建一个方法重载,它可以接受给定参数的两种固定类型之一。

你可以做的最好的事情(虽然仍然避免多次重载)是创建一个新类型,你可以通过两种不同类型之一创建一个实例,并接受那个的实例。

public class MyJSON
{
    public MyJSON(JObject json)
    {
        FirstOption = json;
        FirstOptionValid = true;
    }
    public MyJSON(File json)
    {
        SecondOption = json;
        SecondOptionValid = true;
    }
    public JObject FirstOption { get; private set; }
    public bool FirstOptionValid { get; private set; }
    public File SecondOption { get; private set; }
    public bool SecondOptionValid { get; private set; }

    public static implicit operator MyJSON(File json)
    {
        return new MyJSON(json);
    }
    public static implicit operator MyJSON(JObject json)
    {
        return new MyJSON(json);
    }
}

您甚至可以创建从JObjectFileMyJSON的隐式转化,以便用户可以实际将JObjectFile对象传递给{{ 1}},甚至根本不需要显式构造中间对象。

事实上,使用泛型实际上非常容易将其概括为任何固定数量的类型:

MyMethod

我们现在可以将您的方法编写为:

public class Option<T1, T2>
{
    public Option(T1 value)
    {
        FirstOption = value;
        FirstOptionValid = true;
    }
    public Option(T2 value)
    {
        SecondOption = value;
        SecondOptionValid = true;
    }
    public T1 FirstOption { get; private set; }
    public bool FirstOptionValid { get; private set; }
    public T2 SecondOption { get; private set; }
    public bool SecondOptionValid { get; private set; }

    public static implicit operator Option<T1, T2>(T2 value)
    {
        return new Option<T1, T2>(value);
    }
    public static implicit operator Option<T1, T2>(T1 value)
    {
        return new Option<T1, T2>(value);
    }
}

答案 1 :(得分:1)

两种可能但又很脏的解决方案:

一个(接受对象和类型检查)

public static void MyMethod(object one, object two)
{
    if(one is JObject) // handle
    else if(one is File) // handle
    else throw SomeException();
    ...

第二个参数

相同

二:可选参数

public static void MyMethod(JObject jone = null, File fone = null, 
    JObject jtwo = null, File ftwo = null)
{ 
    if(jone == null && fone == null)
        throw SomeException();
    else
        // use set values and do stuff
    ...

答案 2 :(得分:0)

见下面的代码:

interface IDo {
   void DoSomething();
}

class MyFile : File, IDo {
   void DoSomething() {
       // blah blah
   }
}

class MyJObject : JObject, IDo {
   void DoSomething() {
       // blah blah
   }
}

public static void MyMethod<T1, T2>(T1 one, T2 two)
    where T1 : IDo
    where T2 : IDo
{
   one.DoSomething();
   two.DoSomething();
}

如果文件和/或JObject被密封,则使用包含而不是继承:

class MyFile : IDo {
   File file;
   void DoSomething() {
       // blah blah
   }
}

class MyJObject : IDo {
   JObject jObject;
   void DoSomething() {
       // blah blah
   }
}