Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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#_Linq - Fatal编程技术网

C# 能否返回基于泛型类型的函数?

C# 能否返回基于泛型类型的函数?,c#,linq,C#,Linq,我正在为本质上应该是解析器生成器的东西编写一个简单的概念证明 基本上,我在寻找一种方法来编写一个函数,该函数将返回一个函数,该函数可以从字符串转换为给定类型的某个对象-我希望能够在本质上做到以下几点: Func<string, double> ConvertToDouble = BuildConverter(typeof(0.0)); 作为第一次尝试,我尝试过这样做: public static Func<string, T> BuildParser<T>(

我正在为本质上应该是解析器生成器的东西编写一个简单的概念证明

基本上,我在寻找一种方法来编写一个函数,该函数将返回一个函数,该函数可以从字符串转换为给定类型的某个对象-我希望能够在本质上做到以下几点:

Func<string, double> ConvertToDouble = BuildConverter(typeof(0.0));
作为第一次尝试,我尝试过这样做:

public static Func<string, T> BuildParser<T>(T t)
    {
      if (t is String)
        return new Func<string, T>(x => x.ToString());
      if (t is double)
        return new Func<string, T>(x => double.Parse(x));
    }

这一点都不管用,但它让我觉得有点难以确定我应该采取什么样的方法——因此,任何帮助都将不胜感激

我猜您希望在编译时验证特定的行为。为什么不调用或编写单独的方法来使用呢?if语句所完成的全部工作就是扮演程序员的角色,程序员应该选择合适的转换方法

如果希望在运行时选择行为,则应返回Func,并使该方法非泛型


在方法中使用泛型类型T的问题是,对于方法的每次调用,T是固定的,并且方法中的逻辑假设T在单个调用中变化。在一种情况下,T是字符串,在另一种情况下,T是十进制。编译器无法对此进行排序-它需要允许两个可返回实例具有相同的类型。

我猜您希望在编译时验证特定的行为。为什么不调用或编写单独的方法来使用呢?if语句所完成的全部工作就是扮演程序员的角色,程序员应该选择合适的转换方法

如果希望在运行时选择行为,则应返回Func,并使该方法非泛型


在方法中使用泛型类型T的问题是,对于方法的每次调用,T是固定的,并且方法中的逻辑假设T在单个调用中变化。在一种情况下,T是字符串,在另一种情况下,T是十进制。编译器无法对此进行排序-它需要允许两个可返回实例具有相同的类型。

我不确定您到底想做什么,但是否需要类似的帮助

var stringParser = GetParser<string>();
string s = stringParser("test");

var doubleParser = GetParser<double>();
double d = doubleParser("42");

// ...

public static Func<string, T> GetParser<T>()
{
    return (Func<string, T>)_parserCache[typeof(T)];
}

private static readonly Dictionary<Type, Delegate> _parserCache =
    new Dictionary<Type, Delegate>
        {
            { typeof(string), new Func<string, string>(x => x) },
            { typeof(double), new Func<string, double>(x => double.Parse(x)) }
            // etc
        };

我不确定你到底想做什么,但这有什么帮助吗

var stringParser = GetParser<string>();
string s = stringParser("test");

var doubleParser = GetParser<double>();
double d = doubleParser("42");

// ...

public static Func<string, T> GetParser<T>()
{
    return (Func<string, T>)_parserCache[typeof(T)];
}

private static readonly Dictionary<Type, Delegate> _parserCache =
    new Dictionary<Type, Delegate>
        {
            { typeof(string), new Func<string, string>(x => x) },
            { typeof(double), new Func<string, double>(x => double.Parse(x)) }
            // etc
        };
不能将类与结构类型混合使用。除此之外,它还会起作用

请参阅下面的代码:

private void Testing() {
    var func = BuildParserStruct<double>();
    double value = func("5");
}

public static Func<string, T> BuildParserClass<T>() where T : class
{
    return x => x as T;
}

public static Func<string, T> BuildParserStruct<T>() where T : struct
{
    return (x => (T)Convert.ChangeType(x, typeof(double)));
}
不能将类与结构类型混合使用。除此之外,它还会起作用

请参阅下面的代码:

private void Testing() {
    var func = BuildParserStruct<double>();
    double value = func("5");
}

public static Func<string, T> BuildParserClass<T>() where T : class
{
    return x => x as T;
}

public static Func<string, T> BuildParserStruct<T>() where T : struct
{
    return (x => (T)Convert.ChangeType(x, typeof(double)));
}

ADO.Net有一个执行标量函数,这一直困扰着我,因为它返回一个对象。您可以编写一个泛型包装函数来返回适当的类型。当然,这假设您知道将返回什么类型

有些简化:

    public T ExecuteScalar<T>()
    {
        return (T)Command.ExecuteScalar();
    }

ADO.Net有一个执行标量函数,这一直困扰着我,因为它返回一个对象。您可以编写一个泛型包装函数来返回适当的类型。当然,这假设您知道将返回什么类型

有些简化:

    public T ExecuteScalar<T>()
    {
        return (T)Command.ExecuteScalar();
    }

如果您在泛型函数中查找类型,那么您似乎忽略了泛型的要点。如果您想要运行时决策,那么您不应该使用泛型。如果需要编译时决策,则不应使用is。@Oded-我不确定是否同意,我只是在寻找一种特定类型的类型多态性。如果在泛型函数中查找类型,则似乎缺少泛型的要点。如果需要运行时决策,则不应使用泛型。如果您想要编译时决策,那么就不应该使用is。@Oded-我不确定我是否同意,我只是在寻找一种特定类型的类型多态性。就我的示例而言,您是正确的-不过这只是一个概念证明。最终,我得到了一个消息传递系统,它以逗号分隔的字符串形式发送消息,并且每个消息都可以映射到一个类或结构。这意味着,每当有人在这里编写使用该消息系统的应用程序时,他们都需要手工编写代码,说明如何将其映射到类。从本质上说,我想做的是,通过编写一个映射生成器来实现自动化。就我的示例而言,您是正确的,但这只是一个概念证明。最终,我得到了一个消息传递系统,它以逗号分隔的字符串形式发送消息,并且每个消息都可以映射到一个类或结构。这意味着,每当有人在这里编写使用该消息系统的应用程序时,他们都需要手工编写代码,说明如何将其映射到类。我想做的是,本质上,通过编写一个映射生成器来实现自动化。这看起来很有趣!我试一下——我完全忘记了“where T:”语法。是什么让你认为不能将类与结构类型混合使用?这可以通过一个BuildParser方法完成;如果不想,您不需要单独的BuildParserClass和BuildParserStruct方法。请看我的答案作为例子,这很公平。我应该说的是,如果不使用反射,泛型方法不能同时实例化结构和类类型或派生类型。sin,这个限制不会影响你的解决方案
ce您的泛型方法不会实例化任何内容。。。我发现你的解决方案很聪明,即使limited在处理30种不同的类型时需要30个项目的缓存,等等……这看起来很有趣!我试一下——我完全忘记了“where T:”语法。是什么让你认为不能将类与结构类型混合使用?这可以通过一个BuildParser方法完成;如果不想,您不需要单独的BuildParserClass和BuildParserStruct方法。请看我的答案作为例子,这很公平。我应该说的是,如果不使用反射,泛型方法不能同时实例化结构和类类型或派生类型。此限制不会影响您的解决方案,因为您的泛型方法不会实例化任何内容。。。我发现你的解决方案很聪明,即使limited在处理30种不同的类型时需要30个项目的缓存,等等。。。