Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何创建一个接受一个泛型类型并返回另一个泛型类型的C#泛型方法?_C#_Generics_Methods - Fatal编程技术网

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

如何创建一个接受一个泛型类型并返回另一个泛型类型的C#泛型方法?,c#,generics,methods,C#,Generics,Methods,如何创建一个接受一个泛型类型并返回另一个泛型类型的C#泛型方法?如何获取T的实际类型,以便将新类型作为泛型T类型返回 基本上,我希望实现类似于此示例代码的东西,其中if/else逻辑在类型之间进行转换。如果有更好的方法来做同样的事情,比如使用Func,请让我知道。任何帮助都将不胜感激。多谢各位 编辑: 好的,这几乎正是我想要做的。(只是类型不同)我认为“Convert.ChangeType”不起作用,因为我使用的是自定义类型 public interface ICustomType{}

如何创建一个接受一个泛型类型并返回另一个泛型类型的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;
}
公共接口ICustomType{}
公共结构类型A:ICustomType{}
公共结构类型B:ICustomType{}
公共结构类型C:ICustomType{}
公共静态T转换(ICustomType输入),其中T:ICustomType
{
var输出=默认值(T);
if(输出为A型)
{
if(输入为A型)
{
输出=输入;
}
else if(输入类型为B)
{                
输出=自定义类型B_到类型A_转换器(输入);
}
else if(输入类型为C)
{
输出=自定义类型C_至类型A_转换器(输入);
}
}
else if(输出类型为B)
{
if(输入为A型)
{
输出=自定义类型A\u到类型B\u转换器(输入);
}
else if(输入类型为B)
{                
输出=输入;
}
else if(输入类型为C)
{
输出=自定义类型C_到类型B_转换器(输入);
}
}
else if(输出类型为C)
{
//与上面的样式相同
}
返回输出;
}
可能的用例:

TypeA a = 45;
TypeB result = Convert<TypeB>(a);
TypeA=45;
类型B结果=转换(a);

好吧,如果你对类型一无所知,最好的办法就是按照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));
    }
}
公共静态类程序
{
公共静态void Main()
{
字符串s=“1”;
双d=转换(s);
控制台写入线(d);
}
公共静态TOut转换(TIn文本)
{
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);
    }
publicstaticvoidmain()
{
字符串s=“T”;
//这将引发格式化异常
双d=转换(s);
控制台写入线(d);
}
因此,像这样使用泛型可能不是解决任何问题的最佳方法。

您可以尝试以下方法:

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);
}
publicstaticvoidmain()
{
var str=“1.0”;
十进制结果=转换(str,ConvertToDecimal);
}
公共静态十进制ConvertToDecimal(字符串str)
{
返回decimal.Parse(str);
}
公共静态TOut转换(TIn项,函数f)
{
返回f(项目);
}

好的,休息后我回来了,能够解决我的问题。事实证明,我所要做的就是将我的类型作为约束接口传回,然后在返回它之前将其转换为泛型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;
}
公共接口ICustomType{}
公共结构类型A:ICustomType{}
公共结构类型B:ICustomType{}
公共结构类型C:ICustomType{}
公共静态T转换(ICustomType输入),其中T:ICustomType
{
var输出=默认值(T);
if(输出为A型)
{
if(输入为A型)
{
输出=(T)输入;
}
else if(输入类型为B)
{  
//首先将我的类型分配给ICustomType接口
ICustomType TYPE A=自定义类型B_到类型A_转换器(输入);
//然后在返回该接口之前将其强制转换为泛型T
输出=(T)A型;
}
else if(输入类型为C)
{  
//首先将我的类型分配给ICustomType接口
ICustomType TYPE C=自定义TYPE C_到TYPE A_转换器(输入);
//然后在返回该接口之前将其强制转换为泛型T
输出=(T)类型C;
}
}
else if(输出类型为B)
{
//与上面的样式相同
}
else if(输出类型为C)
{
//与上面的样式相同
}
返回输出;
}

你能举例说明你想做什么吗?。。。编译器也无法推断泛型返回类型。如果泛型类型仅用于return,则在调用该方法时必须指定它。您可能对.Net中仍有大量Convert方法感兴趣,只需使用
Convert即可。
可能重复我将提供有关您实际目标的更多背景信息。我不确定泛型是否适合您的情况…ChangeType将不起作用,因为我使用的是自定义类型。我更新了我的代码示例,以反映我正在处理的实际代码。泛型的主要目的是提供编译时类型安全性…您有一个类似于工厂方法的方法,它尝试基于传递给该方法的另一个实例创建ICustomType的实例。然后,工厂方法本身应该负责了解如何基于特定逻辑创建新实例。你不能真的把这种转换逻辑变成“通用的”。谢谢你的观察,你有什么建议可以让我这样做吗?我现在处于精神障碍。谢谢,就像我说的,实现你的Convert方法,根据你的逻辑执行转换。在方法中创建类型T的实例,并根据输入类型将其属性设置为适当的值。所有不属于通用ICustomType接口的属性都必须使用反射进行设置。只有您才应该知道如何创建给定类型的实例