如何创建一个C#泛型方法,该方法接受一个泛型类型并返回另一个泛型类型?

时间:2016-12-09 10:39:24

标签: c# generics methods

如何创建一个C#泛型方法,该方法接受一个泛型类型并返回另一个泛型类型?我如何得到实际的T类型,以便我可以将我的新类型作为通用T类型返回。

基本上,我希望实现类似这样的示例代码,其中if / else逻辑在类型之间进行转换。如果有更好的方法来做同样的事情,比如使用Func,请告诉我。任何帮助,将不胜感激。谢谢。

修改 好的,这几乎就是我想要做的。 (只是类型不同)我不认为“Convert.ChangeType”会起作用,因为我使用的是自定义类型。

public interface ICustomType{}    
public struct TypeA : ICustomType {}
public struct TypeB : ICustomType {}
public struct TypeC : ICustomType {}

public static T Convert<T>(ICustomType input) where T : ICustomType
{
    var output = default(T);

    if (output is TypeA)
    {
        if (input is TypeA)
        {
            output = input;
        }
        else if (input is TypeB)
        {                
            output = CustomTypeB_ToTypeA_Converter(input);
        }
        else if (input is TypeC)
        {
            output = CustomTypeC_ToTypeA_Converter(input);
        }
    }
    else if (output is TypeB)
    {
        if (input is TypeA)
        {
            output = CustomTypeA_ToTypeB_Converter(input);
        }
        else if (input is TypeB)
        {                
            output = input;
        }
        else if (input is TypeC)
        {
            output = CustomTypeC_ToTypeB_Converter(input);
        }
    }
    else if (output is TypeC)
    {
       // same pattern as above
    }
    return output;
}

可能的用例:

TypeA a = 45;
TypeB result = Convert<TypeB>(a);

3 个答案:

答案 0 :(得分:0)

好吧,如果您对类型一无所知,那么您可以做的最好的事情就是使用Rob和Rabban建议的ChangeType方法:

public static class Program
{
    public static void Main()
    {
        string s = "1";
        double d = Convert<string, double>(s);
        Console.WriteLine(d);
    }

    public static TOut Convert<TIn, TOut>(TIn text)
    {
        return (TOut)System.Convert.ChangeType(text, typeof(TOut));
    }
}

请注意,如果您尝试使用不兼容的值和类型的方法,这将在运行时抛出异常:

    public static void Main()
    {
        string s = "T";
        //THIS WILL THROW A FORMATEXCEPTION
        double d = Convert<string, double>(s);
        Console.WriteLine(d);
    }

因此,使用这样的泛型可能不是解决你想要做的任何事情的最好方法。

答案 1 :(得分:0)

你可以试试这个:

public static void Main()
{
    var str = "1.0";

    decimal result = Convert(str, ConvertToDecimal);
}

public static decimal ConvertToDecimal(string str)
{
    return decimal.Parse(str);
}

public static TOut Convert<TIn, TOut>(TIn item, Func<TIn, TOut> f)
{
    return f(item);
}

答案 2 :(得分:0)

休息好后我回来了,能够解决我的问题。事实证明,我所要做的就是将我的类型作为约束接口传回,然后在返回之前将其转换为通用T.就是这样,一切正常。谢谢大家的帮助。

public interface ICustomType{}    
public struct TypeA : ICustomType {}
public struct TypeB : ICustomType {}
public struct TypeC : ICustomType {}

public static T Convert<T>(ICustomType input) where T : ICustomType
{
    var output = default(T);

    if (output is TypeA)
    {
        if (input is TypeA)
        {
            output = (T)input;
        }
        else if (input is TypeB)
        {  
            // first assign my type to ICustomType interface
            ICustomType typeA =  CustomTypeB_ToTypeA_Converter(input);
            // then cast that interface to the generic T before you return it             
            output = (T)typeA;
        }
        else if (input is TypeC)
        {  
            // first assign my type to ICustomType interface
            ICustomType typeC =  CustomTypeC_ToTypeA_Converter(input);
            // then cast that interface to the generic T before you return it             
            output = (T)typeC;
        }
    }
    else if (output is TypeB)
    {
        // same pattern as above
    }
    else if (output is TypeC)
    {
       // same pattern as above
    }
    return output;
}