如何从通用类型中找出数据类型

时间:2019-05-03 15:29:07

标签: c#

我有一个方法,其中我发送了两个相同类型的参数,并且需要折叠它们。例如,如果这些是数字,则仅返回总和,并且如果这些行是这些行的串联。我该怎么做?而且,如果我传递了无法折叠的类型,则需要抛出异常。

public class Calcul<T>
{
    public static T Add(T c1, T c2)
    {
    }
}

4 个答案:

答案 0 :(得分:1)

Servyin a comment

  

如果该方法实际上不是通用的,则不要使其通用,也不要说该方法实际上不能接受任何类型,就可以接受任何类型。如您所知,如果要处理有限数量的特定类型,则每种类型都有重载。

replied

  

A,我向老师展示了,但是他说不是那样。他说,它应该像一个抽象计算器,在其中您可以为每种类型T定义操作N


您可以使用带有该签名的方法,而根本没有if块,但是Add方法不能是静态的。您必须传递Func<T1, T2, TResult>,其中T1T2TResult是相同的(T):

public class Calculator<T>
{
    private readonly Func<T, T, T> _func;

    public Calculator(Func<T, T, T> func)
    {
        _func = func;
    }

    public T Add(T a, T b)
    {
        return _func(a, b);
    }
}

您将像这样使用它:

Func<int, int, int> intAddition = (a, b) => a + b;
var intCalculator = new Calculator<int>(intAddition);
Console.WriteLine(intCalculator.Add(1, 2)); // writes 3

Func<string, string, string> stringAddition = (a, b) => a + b;
var stringCalculator = new Calculator<string>(stringAddition);
Console.WriteLine(stringCalculator.Add("Hello ", "world")); // writes "Hello world"

在线示例:https://dotnetfiddle.net/8NOBsv


通过这种方式,您可以指定Add方法的逻辑,并且没有大量的重载方法(或方法内部的可怕的类型检查逻辑,例如if ( typeof(T) == typeof(string) )等。< / p>

答案 1 :(得分:0)

您可以typeof(T)始终获取类型信息。使用它,您可以使用条件语句来通过逻辑工作

示例:

var type = typeof(T);
if (type == int)
{ do something ;}

泛型用于以下情况:2种不同类型,它们遵循相同的操作,但采用不同的输入类型和输出类型。基本用法是它们具有相同的过程。如果您经常使用特定于类型的进程,那么最好根据您的需要重载函数。

深入了解您的用例:

尝试重载方法。

private static int doSomething(int n1, int n2)
    {           
        return (n1) + (n2);  
    }

    private static float doSomething(float n1, float n2)
    {
        return (n1) - (n2);
    }

答案 2 :(得分:0)

这是一种通用的方法,只要T支持+运算符即可。但是,它使用运行时检查。据我所知,在编译时无法使用类型约束进行检查。

改编自:https://stackoverflow.com/a/5997156/6713871

public class Calcul<T>
{
    public static T Add(T c1, T c2)
    {
        return (dynamic)c1 + (dynamic)c2;
    }
}

答案 3 :(得分:0)

正如其他人所说,您可能应该使用重载。但是可以做这样的事情

static class Calc<T>
{
    public static T Add(T a, T b)
    {
        if (typeof(T) == typeof(int))
        {
            return (T)(object)((int)(object)a + (int)(object)b);
        }

        if (typeof(T) == typeof(uint))
        {
            return (T)(object)((uint)(object)a + (uint)(object)b);
        }

        throw new ArgumentOutOfRangeException($"Type {typeof(T).Name} is not supported.");
    }    
}

并调用:

Calc<int>.Add(1 , 2); // returns 3
Calc<double>.Add(2d, 3d).Dump(); // throws exception