我正在编写一个简单的概念证明,本质上应该是一个解析器生成器。
基本上我正在寻找一种方法,我可以编写一个函数,它将返回一个从字符串转换为给定类型的某个对象的函数 - 我希望能够在本质上执行以下操作:
Func<string, double> ConvertToDouble = BuildConverter(typeof(0.0));
显然这是一个非常人为的例子 - 但如果我可以做简单的版本,那么我应该能够做更复杂的版本!
FWIW,我最终要做的是将一串值映射到一个类,但为了使它尽可能灵活,我想通过一个函数返回一个函数来完成它转换。在功能方面,我想我想要的东西看起来像这样:
a -> (string -> a)
作为第一次尝试,我尝试过这样做:
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));
}
这根本不起作用,但是让我感到有点担心我应该采取什么方法 - 所以任何帮助都会非常感激!
答案 0 :(得分:0)
我猜你想要在编译时验证特定的行为。为什么不直接调用Convert或编写单独的方法?你的if语句所完成的就是承担应该选择适当转换方法的程序员的角色。
如果您想要在运行时选择行为,则应返回Func<string, object>
,并使该方法不是通用的。
在方法中使用泛型类型T的问题是每次调用方法时T都是固定的,并且方法中的逻辑假设T在一次调用中变化(在一种情况下T是一个字符串,在另一种情况T是小数)。编译器无法对此进行排序 - 它需要允许两个可返回实例具有相同的类型。
答案 1 :(得分:0)
我不确定你到底想要做什么,但这会有什么帮助呢?
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
};
答案 2 :(得分:0)
您不能将class
与struct
类型混合使用。除此之外,它将起作用。
请参阅以下代码:
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)));
}
答案 3 :(得分:0)
ADO.Net有一个Execute Scalar函数,它总是困扰我,因为它返回一个对象。您可以编写通用包装函数来返回适当的类型。当然,这假设你知道将返回什么类型。
有点简化:
public T ExecuteScalar<T>()
{
return (T)Command.ExecuteScalar();
}