This question already has answers here:
Generic TryParse
                                
                                    (23个答案)
                                
                        
                                3年前关闭。
            
                    
有几个功能几乎相同(或者可以使用类型参数轻松实现不同的部分)。但是,每个函数调用一个不同的TryParse()函数是一个区别。

void Fun1<T>(T p) where T : IBase // simplified
{ ......
    int x;
    if(int.TryParse(p.S, out x)) { .... }
}

void Fun1<T>(T p) where T : IBase
{ ......
    decimal x;
    if(decimal.TryParse(p.S, out x)) { .... }
}
......


如何为这些函数创建类型参数为int,decimal,double,short,...(方法为TryParse的任何类型)的泛型方法?

最佳答案

这是有关C#中基于约束的泛型的痛苦现实之一,您想说您将支持具有所需签名的方法TryParse的任何类型,但您正在使用的类型上没有此类接口,并且在其上添加这样的接口。不幸的是,您还需要增加一个麻烦,就是需要泛泛地引用静态方法(因为TryParse是类型上的静态方法)。

这里真正需要的是C ++样式模板,它们可以在C ++ \ CLI中作为托管模板使用,但是由于将静态方法称为“泛型”,因此即使这样也有些复杂。 C ++模板向导可以助您一臂之力,但是为了省事,您可以使用一个不错的旧T4模板来模仿C ++要做的事情,减去任何额外的模板元编程。

我创建了以下T4模板:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>

<#
    List<string> types = new List<string>() { "decimal", "int" };
    foreach (string t in types)
    {
#>
void Fun1(<#=t#> p) // simplified
{ //......
    <#=t#> x;
    if(<#=t#>.TryParse(p.S, out x)) { /*....*/ }
}

<#
}
#>


这给了我以下输出:

void Fun1(decimal p) // simplified
{ //......
    decimal x;
    if(decimal.TryParse(p.S, out x)) { /*....*/ }
}

void Fun1(int p) // simplified
{ //......
    int x;
    if(int.TryParse(p.S, out x)) { /*....*/ }
}


我认为这大致就是您要寻找的。我认为在您的情况下,这是避免所有反射事件或落入托管模板(对于静态方法调用仍可能会产生反射飞溅)或什至更深入到C ++的最简单解决方案。 T4方法输出一个.cs文件,因此编译器将警告您有关问题的警告,就像项目中其他任何.cs文件的警告一样。

关于c# - 包含T.TryParse(x,out y)的泛型函数? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35640906/

10-13 03:15