【问题标题】:Using C# generics to create a mapper method with different return types使用 C# 泛型创建具有不同返回类型的映射器方法
【发布时间】:2023-03-26 01:15:01
【问题描述】:

我正在尝试创建一种将 int 映射到 string 并将 string 映射到 int 的方法。我有想法用一种方法来做,但不确定这是否可行。

我已经走到这一步了:

class MappingWithGenerics
    {
        [Test]
        public void IntToString()
        {
            string actual = Map<int, string>(1);
            Assert.AreEqual("1", actual);
        }

        [Test]
        public void StringToInt()
        {
            int actual = Map<string, int>("1");
            Assert.AreEqual(1, actual);
        }

        public TOut Map<Tin, TOut>(Tin element)
        {
            if(element.GetType() == typeof(int))
                return element.ToString();
            return Convert.ToInt32(element);
        }
    }

这会产生编译错误。

无法将类型“int”隐式转换为“TOut”

无法将类型“字符串”隐式转换为“TOut”

知道如何实现 Map 方法吗?

【问题讨论】:

  • “这会产生编译错误” - 什么 编译错误?错误信息是什么?什么线?请不要让我们为您尝试,只是为了获得与您已有的信息相同的信息。
  • 话虽如此,if(element.GetType() == typeof(int)) 可能是一个危险信号。一般来说,您应该完全在您希望所有类型的相同行为的地方使用泛型,因此区分您正在查看的类型似乎是矛盾的。
  • 您的方法签名说它正在返回一个TOut 对象,但您正试图返回一个stringint。您的泛型在这里没有用处。
  • 抱歉,编译错误是:无法将类型'int'隐式转换为'TOut' 无法将类型'string'隐式转换为'TOut'

标签: c# generics


【解决方案1】:

泛型适用于您希望在一堆不同类型中具有相同功能的情况。在这种情况下,您正在处理两种特定类型,并且您希望它们之间具有不同的功能。泛型并不是您真正想要的,尤其是当您可以通过简单的方法重载来做同样的事情时:

class MappingWithoutGenerics
{
    public string Map(int x)
    {
        return x.ToString();
    }

    public int Map(string s)
    {
        return Convert.ToInt32(s);
    }
}

【讨论】:

  • 这适用于这两种情况,但这并不是我真正想要的。如果想从 int 映射到 bool 怎么办?映射(1)
【解决方案2】:

您的代码无法编译的原因是您编写的 generic 方法只考虑了两种特定类型。您可以通过转换为 object 将其硬塞到通用函数中,但这不是一个好主意。

您可以使用Convert 类实现所需的功能,如下所示:

public static TOut Map<Tin, TOut>(Tin element) {
    return (TOut)Convert.ChangeType(element, typeof(TOut));
}

您的测试方法无需更改即可工作。但是,该方法将能够在string->intint->string 之外进行转换:您将能够在Convert.ChangeType 方法支持的任何一对类型之间进行转换。

Demo.

【讨论】:

    【解决方案3】:

    你可以像这样实现这个方法:

        public TOut Map<Tin, TOut>(Tin element)
        {
            object outValue;
            if(element.GetType() == typeof(int))
                outValue = element.ToString();
            else
                outValue = Convert.ToInt32(element);
            return (TOut)outValue;
        }
    

    但我真的很奇怪你为什么需要这样的方法。我确信有更好的方法来解决您的更广泛的问题。

    【讨论】:

    • 我想要实现的比实际示例要复杂一些。它更像是类之间的映射,但它不想用复杂的例子来问这个问题。还是谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多