C# 在C语言中使用模式匹配选择合适的方法#
目前我正在做一个C#的大学项目,其中包括将一种形式的代码转换为另一种形式的代码,包括从许多可用的方法中选择合适的方法/函数。这里的问题是,使用任何模式匹配技术来实现这一点,而不是使用许多IF-ELSE语句 现在,我已经使用嵌套的IF-ELSE语句实现了这一点,它填充了整个程序,看起来像是完成时的幼稚代码 目前的执行情况:-- 输入:C# 在C语言中使用模式匹配选择合适的方法#,c#,asp.net,.net,pattern-matching,C#,Asp.net,.net,Pattern Matching,目前我正在做一个C#的大学项目,其中包括将一种形式的代码转换为另一种形式的代码,包括从许多可用的方法中选择合适的方法/函数。这里的问题是,使用任何模式匹配技术来实现这一点,而不是使用许多IF-ELSE语句 现在,我已经使用嵌套的IF-ELSE语句实现了这一点,它填充了整个程序,看起来像是完成时的幼稚代码 目前的执行情况:-- 输入: //stored in list<string> get(3 int) //type1 get(int:a,b,c) //type2 get
//stored in list<string>
get(3 int) //type1
get(int:a,b,c) //type2
get(name) //type3
//list passed to ProcessGET method
//存储在列表中
get(3 int)//type1
get(int:a,b,c)//type2
get(name)//type3
//传递给ProcessGET方法的列表
使用if-else:
public string ProcessGET(List<string> inputData)
{
foreach(var item in inputData)
{
if (inputData.item.Split('(')[1].Split(')')[0].Contains(':'))
{
return Type2 result;
}
else if (!inputData.item.Split('(')[1].Split(')')[0].Contains(':') && Convert.ToInt32(inputData.item.Split('(')[1].Split(')')[0].Split(' ')[0])>0)
{
return Type1 result;
}
else
{
return Type3 result;
}
}
}
公共字符串ProcessGET(列出inputData)
{
foreach(inputData中的var项)
{
如果(inputData.item.Split(“(”)[1]。Split(“)”)[0]。包含(“:”)
{
返回Type2结果;
}
如果(!inputData.item.Split('(')[1].Split(')')[0]。包含(':')和转换.ToInt32(inputData.item.Split('(')[1].Split('))[0].Split('[0])>0,则为else
{
返回Type1结果;
}
其他的
{
返回Type3结果;
}
}
}
我想要的是这样的
/stored in list<string>
get(3 int) //type1
get(int:a,b,c) //type2
get(name) //type3
//list passed to ProcessGET method
public string ProcessGET(List<string> inputData)
{
foreach(var itm in inputData)
{
// call appropriate method(itm) based on type using some pattern matching techniques
}
}
string Method1(var data)
{
return result for type1;
}
string Method2(var data)
{
return result for type2;
}
string Method3(var data)
{
return result for type3;
}
/存储在列表中
get(3 int)//type1
get(int:a,b,c)//type2
get(name)//type3
//传递给ProcessGET方法的列表
公共字符串ProcessGET(列表inputData)
{
foreach(输入数据中的var itm)
{
//使用一些模式匹配技术基于类型调用适当的方法(itm)
}
}
字符串方法1(变量数据)
{
返回type1的结果;
}
字符串方法2(变量数据)
{
返回type2的结果;
}
字符串方法3(变量数据)
{
返回type3的结果;
}
通常,我的程序主要针对各种类型的输入关键字(如“get”、“output”、“declare”等)执行此类工作。。。其中Get转换为Scanf语句,输出为printf语句,等等。
在这种情况下,如果我使用if-ELSE,我的项目将充满if-ELSE语句
由于我刚开始学习C#,我不知道是否存在这样的东西(谷歌搜索,但没有找到我要找的东西),所以任何关于这个问题的帮助都将对进一步的开发非常有帮助(有用)
非常感谢。我会在这里留下一些建议,供您参考。下面是一些基本代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace TestStuff
{
class Program
{
//Input string should be of the form "<type>:<index>"
static dynamic GiveMeSomethingDynamic(string someInput)
{
/* predefined arrays sothat we can return something */
string[] _storedStrings = { "Word 1", "word 2", "word 3" };
int[] _storedInts = { 1, 2, 3 };
float[] _storedFloats = { 3.14f, 2.71f, 42.123f };
/* Parse the input command (stringly typed functions are bad, I know.) */
string[] splitted = someInput.Split(':');
string wantedType = splitted[0];
int index = int.Parse(splitted[1]);
/* Decide what to return base on that argument */
switch (wantedType)
{
case "int":
return _storedInts[index];
case "string":
return _storedStrings[index];
case "float":
return _storedFloats[index];
//Nothing matched? return null
default:
return null;
}
}
static void Main(string[] args)
{
/* get some return values */
dynamic firstOutput = GiveMeSomethingDynamic("string:0");
dynamic secondOutput = GiveMeSomethingDynamic("int:1");
dynamic thirdOutput = GiveMeSomethingDynamic("float:2");
/* Display the returned objects and their type using reflection */
Console.WriteLine("Displaying returned objects.\n" +
"Object 1: {0}\t(Type: {1})\n" +
"Object 2: {2}\t\t(Type: {3})\n" +
"Object 3: {4}\t\t(Type: {5})\n",
firstOutput, firstOutput.GetType(),
secondOutput, secondOutput.GetType(),
thirdOutput, thirdOutput.GetType());
/* Act on the type of a object. This works for *all* C# objects, not just dynamic ones. */
if (firstOutput is string)
{
//This was a string! Give it to a method which needs a string
var firstOutputString = firstOutput as string; //Cast it. the "as" casting returns null if it couldn't be casted.
Console.WriteLine("Detected string output.");
Console.WriteLine(firstOutputString.Substring(0, 4));
}
//Another test with reflection.
Console.WriteLine();
//The list of objects we want to do something with
string[] values = { "string:abcdef", "int:12", "float:3.14" };
foreach(var value in values)
{
/* Parse the type */
string[] parsed = value.Split(':');
string _type = parsed[0];
string _argument = parsed[1];
switch (_type)
{
case "string":
//This is a string.
string _stringArgument = _argument as string;
Method1(_stringArgument);
break;
case "int":
//Do something with this int
int _intArgument = int.Parse(_argument);
Method2(_intArgument);
break;
case "float":
float _floatArgument = float.Parse(_argument);
Method3(_floatArgument);
break;
default:
Console.WriteLine("Unrecognized value type \"{0}\"!", _type);
break;
}
}
Console.ReadLine();
}
public static void Method1(string s) => Console.WriteLine("String Function called with argument \"{0}\"", s);
public static void Method2(int i) => Console.WriteLine("int Function called with argument {0}", i);
public static void Method3(float f) => Console.WriteLine("float Function called with argument {0}", f);
}
}
“老派”方法(不使用dynamic
)只将对象
类型传递到每个函数中,但解析是等效的(if(someArgument.GetType()==typeof(string))
…)
希望本文能为您提供一些有关如何解析这些字符串、将它们转换为不同类型以及使用它调用不同函数的想法。因此这些类型将作为字符串存储在列表中,对吗?您想根据字符串的值调用不同的函数吗 下面是我将如何完成您的代码:
public interface IMyType
{
string Result();
string Input {get; set;}
}
public class Type1 : IMyType
{
public string Result()
{
// do something
}
public string Input {get; set;}
}
(对类型2和类型3重复此操作) public IMyType GetAppropriateType(string input)
{
if (inputData.item.Split('(')[1].Split(')')[0].Contains(':'))
{
return new Type2 {Input = input};
}
//etc
}
public string ProcessGET(List<string> inputData)
{
foreach(var itm in inputData)
{
IMyType type = GetAppropriateType(itm);
type.Result();
}
}
public IMyType getpropertype(字符串输入)
{
如果(inputData.item.Split(“(”)[1]。Split(“)”)[0]。包含(“:”)
{
返回新的Type2{Input=Input};
}
//等
}
公共字符串ProcessGET(列表inputData)
{
foreach(输入数据中的var itm)
{
IMyType type=getpropertype(itm);
type.Result();
}
}
可能也值得为字符串匹配查看正则表达式解决此问题的另一个通用方法是引入一个接口,例如
IMatcher
。该接口有一个方法Match
,该方法返回您的类型或完全转换的行
您可以创建多个实现IMatcher
的类
然后,主循环变为:
var matchers = new [] { new MatcherA(), new MatcherB(), ... };
foreach (string line in input)
foreach (matcher in matchers)
{
var match = matcher.Match(line);
if (match != null) return match;
}
没有更大的if语句。每个matcher都有自己的小类,您可以为每个类编写单元测试。另外,使用正则表达式可以简化匹配程序。您能告诉我们您的实际代码吗<类型3(var数据)的代码>函数无效。我也很难理解你所说的
get(3int)
。您在谈论重载吗?动态
关键字作为返回类型允许您返回任意值。然后,您可以使用typeof
操作符检查返回内容的类型,也许可以尝试深入研究该材料,看看是否可以在您的案例中使用它。(public dynamic ProcessGET()
然后可以返回Type1
、Type2
和Type3
对象,没有问题。)@Rob这些get()输入方法是我自己的自定义语法。@MaximilianGerhardt-如果我的意思不正确,很抱歉。实际上,我总是从所有方法返回字符串值。转换代码的更好方法是构建(或使用现有的)解析器,该解析器在内存中构建抽象语法树,然后使用语法树上的“访问者模式”将其转换为所选输出。这可能超出了本项目的范围,但值得阅读这些概念,以了解解决问题的更好方法。感谢您的解决方案。我认为,与直接使用“IF-ELSE”语句相比,这种方法绝不会减少“IF”语句的数量,但它将有助于隐藏“IF”语句的大量使用。ProcessGET()方法的foreach(…)循环中的3个条件检查语句(IF、IF-ELSE、ELSE)被移动到单独的方法中,在该方法中执行相同的操作。但是,正如我所说,它有助于隐藏/分离这些条件语句。感谢您提供了许多有用的附加信息。我想知道我是否能使用这些动态类型是的,这会减少。我会试试
var matchers = new [] { new MatcherA(), new MatcherB(), ... };
foreach (string line in input)
foreach (matcher in matchers)
{
var match = matcher.Match(line);
if (match != null) return match;
}