【问题标题】:Choose return type based calling structure选择基于返回类型的调用结构
【发布时间】:2014-04-30 17:42:06
【问题描述】:

我确信这对于有经验的程序员来说是一个简单的问题,但我以前从未这样做过 - 假设我有一个如下所示的自定义对象:

public class MyClass
{       
    public Dictionary<string,string> ToDictString()
    {
        Dictionary<string,string>  retval = new Dictionary<string,string>;
        // Whatever code
        return retval;
    }

    public Dictionary<string,int> ToDictInt()
    {
        Dictionary<string,int>  retval = new Dictionary<string,int>;
        // Whatever code
        return retval;
    }

}

所以,在我的代码中,我可以写如下内容:

MyClass FakeClass = new MyClass();
Dictionary<string,int> MyDict1 = FakeClass.ToDictInt();
Dictionary<string,string> MyDict2 = FakeClass.ToDictString();

这很好用,但我想做的是在MyClass 中调用一个方法,比如ToDict()可以根据预期的返回类型返回任一类型的字典

所以,例如,我会:

MyClass FakeClass = new MyClass();

// This would be the same as calling ToDictInt due to the return type:
Dictionary<string,int> MyDict1 = FakeClass.ToDict();

// This would be the same as calling ToDictString due to the return type:
Dictionary<string,string> MyDict2 = FakeClass.ToDict();    

所以,一个方法名称,但它知道要根据要返回的变量返回什么...我将如何在我的类中编写方法来做到这一点?

非常感谢!!

【问题讨论】:

  • 不可能像您描述的那样,但您可以定义一个通用方法并在每次调用时使用适当的类型,因此签名将是:Dictionary&lt;string, T&gt; ToDict&lt;T&gt;()。这与您要求的有点不同,但可能值得一提。

标签: c# class methods


【解决方案1】:

这是不可能的。重载解析算法没有考虑方法调用表达式的上下文,因此会导致您提到的示例中出现歧义错误。

您需要有两个不同的方法名称(或参数列表中的不同),这些方法才能具有不同的返回类型。

【讨论】:

  • 为了进一步说明这一点,假设您要调用方法而不将值分配给变量。
  • 即使在比 C# 更宽容的 C++ 中,重载也不能只因返回类型而异。
  • 一如既往地感谢@servy! - 我担心是这样的......我想知道它是因为代码看起来像这样:DataRow dr = new DataRow();; string myfield = dr.Field&lt;string&gt;("FieldName"); 在那里你可以投射你从 Field() 方法中得到的东西......
  • @JohnBus​​tos 这并没有将可能的返回类型限制为两种可能性。它正在编写一个 single 重载,支持 每个可能的类型 作为返回类型。它也根本不考虑上下文。表达式dr.Field&lt;string&gt;("FieldName"); 有一个类型,该类型是string。不需要上下文来确定其类型,这与 lambdas 不同,后者实际上确实需要它们的上下文来确定类型。
  • @JohnBus​​tos - 鉴于您正在寻找类似 DataRow 的功能,我认为 Eric J 的解决方案正是您想要的。
【解决方案2】:

您可以使用泛型来实现接近您想要的东西

public Dictionary<string,T> ToDict<T>()
{
    Dictionary<string,T>  retval = new Dictionary<string,T>();
    // Whatever code
    return retval;
}

使用时需要指定类型参数

var result = myClass.ToDict<int>();

这会将返回类型限定符从方法名称移动到类型参数,并且由于@Servy 提到的问题,这是您可以获得的最接近的。

【讨论】:

  • 这里的问题是您没有将字典限制为只有两种可能的返回类型;可以提供任何可能的类型。如果您在运行时检查它,那么您就失去了静态类型。仅当任何可能的类型确实有效时才应该这样做,在这种情况下,使用重载不是有效的替代方案。
  • @Servy:是的,尽管在提供的示例中同时使用了 stringint,但没有涵盖 OP 需要支持的类型的 where 限制。只是提到一个对 OP 的实际问题可能有用也可能没有用的选项。
  • 非常感谢,埃里克! - 我也在考虑类似的事情,甚至使用我的类中的枚举来定义返回类型......我只是希望我什至不需要走那么远......不过,谢谢你的好主意! !!
  • @JohnBus​​tos 假设只有intstring 有效(或任何其他可能的有限返回类型集),此解决方案产生的问题比它解决的问题多得多。与此解决方案不同,调用者和实现仅具有不同的重载会更容易,并且它还保持静态类型安全。
  • @Servy: assuming only int and string are valid... 我同意你的看法,如果该约束有效的话。 OP 可能真的想支持也可能不想支持广泛的类型。如果他正在查看他的一个 cmets 中暗示的 Field&lt;T&gt; 之类的内容,那么您的假设可能不成立。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 2019-10-29
  • 2019-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多