Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/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#_Asp.net_Enumeration_Ternary Operator - Fatal编程技术网

C# 使用自定义编译器进行枚举的自定义三值运算符

C# 使用自定义编译器进行枚举的自定义三值运算符,c#,asp.net,enumeration,ternary-operator,C#,Asp.net,Enumeration,Ternary Operator,我最近发现自己在想,除了枚举之外,是否存在一个类似于三元运算符的运算符。。。。这可能是一个句柄工具,用于编写更少的代码来处理枚举值 我找不到任何东西,所以我提出了这个问题 如何构建自己的运算符来处理如下所述的枚举 以下面的枚举为例: public enum ComTypes { Call, Email, SMS } 假设我需要根据ComType指定弹出对话框的标题。目前我可以使用三元运算符,如下所示: ComTypes comType = ...; var title = comType =

我最近发现自己在想,除了枚举之外,是否存在一个类似于三元运算符的运算符。。。。这可能是一个句柄工具,用于编写更少的代码来处理枚举值

我找不到任何东西,所以我提出了这个问题

如何构建自己的运算符来处理如下所述的枚举

以下面的枚举为例:

public enum ComTypes { Call, Email, SMS } 
假设我需要根据ComType指定弹出对话框的标题。目前我可以使用三元运算符,如下所示:

ComTypes comType = ...;
var title = comType == ComTypes.Call ? "Make a Call" : 
    comType == ComTypes.Email ? "Send an Email" : 
    /* ComTypes.SMS */ "Send a Text";

我想要的是得到一个更干净更简洁的格式和一个新的枚举运算符。。。如下所示:

ComTypes comType = ...;
var title = comType ? 
    .Call: "Make a Call", 
    .Email: "Send an Email", 
    .SMS|default: "Send a Text";
所以我想我的第一个问题是:

我可以创建一个自定义运算符并与普通C编译器并行使用吗? 假设我可以创建操作符,我可以使用吗?作为枚举运算符,即使标准三值运算用于布尔值? 我知道我可以去谷歌看这篇文章,但如果有人对优秀的编译器创作文章有任何建议,那就太好了。 -编辑-


我只想把这个拿上来。。。我知道如果这阻止了我进行开发,那是不现实的。。。我知道如何通过其他几种方式实现这一点。。。我想在这里得到一些帮助,了解我实现我概述的目标的出发点。。。仅仅是为了尝试编写代码并了解更多我每天使用的框架的乐趣。

为什么不使用切换呢

string title = "";

switch (comType)
{
  case (ComTypes.Call):
    title = "Make a Call";
    break;
  case (ComTypes.Email):
    title = "Send an Email";
    break; 
  case (ComTypes.SMS):
    title = "Send a Text";
    break;
}

你为什么不想用开关呢

string title = "";

switch (comType)
{
  case (ComTypes.Call):
    title = "Make a Call";
    break;
  case (ComTypes.Email):
    title = "Send an Email";
    break; 
  case (ComTypes.SMS):
    title = "Send a Text";
    break;
}

在我看来,您希望将枚举用作哈希表。为什么不直接使用哈希表呢

Dictionary<ComTypes,String>

在我看来,您希望将枚举用作哈希表。为什么不直接使用哈希表呢

Dictionary<ComTypes,String>

三元运算符在C中不是重载运算符

话虽如此,我建议采用简明的:

public enum ComTypes { Call = 0, Email = 1, SMS = 2 };
public readonly string[] ComTitles = 
     { "Make a Call", "Send an Email", "Send a Text" };
稍后在代码中,您可以使用

ComTitles[comType]

三元运算符在C中不是重载运算符

话虽如此,我建议采用简明的:

public enum ComTypes { Call = 0, Email = 1, SMS = 2 };
public readonly string[] ComTitles = 
     { "Make a Call", "Send an Email", "Send a Text" };
稍后在代码中,您可以使用

ComTitles[comType]

根据您对其他答案的评论,您似乎希望将此作为一个学习练习,而不是在生产代码中使用的东西,因此,尽管我建议对任何其他情况都使用一些非常好的答案,但以下是一些通过自定义编译器实现的方法:

编写一个运行预构建的应用程序,扫描所有C文件以获取自定义语法,并在将其输入编译器之前用switch语句替换它。 使用内置的自定义语法编写自己的完整C编译器。NETC编译器不是开源的AFAIK 修改以包含新语法。这可能是最简单的解决方案,您仍然会学到很多关于如何将C编译成CIL然后进行JITTE的知识。
还要注意的是,语法要求您在词汇流中遥遥领先,以确定您是在寻找三元运算符还是新运算符。

根据您对其他答案的评论,您似乎希望将此作为一个学习练习,而不是在生产代码中使用,因此,尽管对于任何其他情况,我都会推荐几个非常好的答案,但以下是一些通过自定义编译器实现的方法:

编写一个运行预构建的应用程序,扫描所有C文件以获取自定义语法,并在将其输入编译器之前用switch语句替换它。 使用内置的自定义语法编写自己的完整C编译器。NETC编译器不是开源的AFAIK 修改以包含新语法。这可能是最简单的解决方案,您仍然会学到很多关于如何将C编译成CIL然后进行JITTE的知识。
还请注意,语法要求您在词汇流中向前看很远,以确定您是在看三元运算符还是新运算符。

好的,至于方法:我不能给您任何确切的答案,但按照您所述的方式,这种情况几乎是不可能的

代码编译器完全是。。陛下密封的。它是单片的,有一些较小的扩展点,请参见ExtensionMethods和LINQ子带。如果你真的发现LINQ子语言插件是如何连接到编译器上的,请给我写个便条。我对此表示怀疑,我相信LINQ语法是硬编码到编译器中的,但也许我错了

但是如果我没有错的话,那么添加操作符是完全不可能的,至少在你看来是这样。当然还有其他方法

查看XAML或ASPX文件或RESX?编译器是如何处理它们的,嗯?构建项目是一个多步骤的过程。解析XAML/ASPX/RESX文件是在C代码编译之前进行的。读取这些文件后,工具将生成.g.cs/.Designer.cs/aspx.cs/.resx.cs文件,然后将这些文件添加到编译集中,然后 ML/ASPX/RESX实际上不是由C编译器编译的

这是什么意思?这意味着您可以将文件的扩展名更改为,例如,.blargh,然后编写一个插件,如XAML/ASPX/RESX parser/generator,将.blargh预处理为.cs,瞧。在.blargh中,您有自己额外的语法优势,翻译成详细的C,然后由普通的C编译器编译

但请注意,虽然它实际上工作得很好,但更改文件扩展名肯定会解除Intellisense和其他csharpy IDE实用程序的绑定,我敢打赌,您不想为了您的全新代码文件扩展名(实际上是全新的语言)几乎从头重写它们

但是等等,还有更多,而且更简单

您甚至不需要.blargh文件类。项目结构是基于MSBuild构建系统构建的。在您的驱动器的某个地方有一堆XML脚本,它们描述了构建系统在解决方案构建或项目构建期间执行的每一个步骤。它们是可编辑的,甚至更好,它们是可扩展的。您可以将插件写入构建系统,并将其插入到构建过程的任何现有步骤之间

想象一下它的简单性:您编写了一个简单的搜索替换实用程序,它用您额外的标记加载一个C文件,对其进行处理,然后写回扩展的、转换为普通的C。您可以在编译阶段之前插入它,您就可以解决您的问题了

要记住一件事:您不能覆盖原始文件。这是不明智的,因为这意味着您与新操作员简要编写的所有内容将在构建时自动扩展并永久替换您需要将扩展文件写入某个临时文件,将该文件添加到“生成”下的当前临时编译文件集中,并删除原始文件,因为不再需要该文件


您应该注意到,XAML/RESX/也正是如此。。文件和.g.cs/.resx.cs/。。。临时人员。这是因为这是在VS/MSBuild系统中处理此类情况的正常方法:如果不想构建新的语言支持,请在您的语言和某些已知语言之间进行翻译,然后将其添加为预处理步骤。就这些。

好的,至于如何回答:我不能给你任何确切的答案,但你所说的情况几乎是不可能的

代码编译器完全是。。陛下密封的。它是单片的,有一些较小的扩展点,请参见ExtensionMethods和LINQ子带。如果你真的发现LINQ子语言插件是如何连接到编译器上的,请给我写个便条。我对此表示怀疑,我相信LINQ语法是硬编码到编译器中的,但也许我错了

但是如果我没有错的话,那么添加操作符是完全不可能的,至少在你看来是这样。当然还有其他方法

查看XAML或ASPX文件或RESX?编译器是如何处理它们的,嗯?构建项目是一个多步骤的过程。解析XAML/ASPX/RESX文件是在C代码编译之前进行的。读取这些文件后,工具将生成.g.cs/.Designer.cs/aspx.cs/.resx.cs文件,然后将这些文件添加到编译集中,而XAML/aspx/resx实际上不是由C编译器编译的

这是什么意思?这意味着您可以将文件的扩展名更改为,例如,.blargh,然后编写一个插件,如XAML/ASPX/RESX parser/generator,将.blargh预处理为.cs,瞧。在.blargh中,您有自己额外的语法优势,翻译成详细的C,然后由普通的C编译器编译

但请注意,虽然它实际上工作得很好,但更改文件扩展名肯定会解除Intellisense和其他csharpy IDE实用程序的绑定,我敢打赌,您不想为了您的全新代码文件扩展名(实际上是全新的语言)几乎从头重写它们

但是等等,还有更多,而且更简单

您甚至不需要.blargh文件类。项目结构是基于MSBuild构建系统构建的。在您的驱动器的某个地方有一堆XML脚本,它们描述了构建系统在解决方案构建或项目构建期间执行的每一个步骤。它们是可编辑的,甚至更好,它们是可扩展的。您可以将插件写入构建系统,并将其插入到构建过程的任何现有步骤之间

想象一下它的简单性:您编写了一个简单的搜索替换实用程序,它用您额外的标记加载一个C文件,对其进行处理,然后写回扩展的、转换为普通的C。您可以在编译阶段之前插入它,您就可以解决您的问题了

要记住一件事:您不能覆盖原始文件。这是不明智的,因为这意味着您与新操作员简要编写的所有内容将在构建时自动扩展并永久替换如果要将扩展文件写入某个临时文件,请将该文件添加到当前临时文件 在build下设置y编译文件,并删除原始文件,因为不再需要它


您应该注意到,XAML/RESX/也正是如此。。文件和.g.cs/.resx.cs/。。。临时人员。这是因为这是在VS/MSBuild系统中处理此类情况的正常方法:如果不想构建新的语言支持,请在您的语言和某些已知语言之间进行翻译,然后将其添加为预处理步骤。仅此而已。

显然我可以使用switch语句,我想知道的一些原因是为了doe的可读性和减少代码行。。。最后,我更想知道我如何才能做到这一点。。。这是关于学习更多关于我如何做那样的事情。你知道我们大多数开发者都有好奇心。。。我只是想学习如何写我自己的shortcuts@MichaelGearhardt…很明显,您不想为此使用KeyValuePair、Dictionary或Tuple[]或其他任何东西。。所以,只要更新你的问题,不要使用任何明显的解决方案,并给出它们的列表。@MichaelGearhardt没关系。没有人知道什么对你来说是显而易见的,什么是不显而易见的,而你却不说。回答得好,但是对于devils advocate在我的帖子中关于更改枚举定义的-1的回应,我建议您显式定义一个case ComTypes.SMS,不要使用默认值,因为更改枚举定义同样会导致magic停止工作。显然,我可以使用switch语句,我好奇的一些原因是doe的可读性和减少代码行数。。。最后,我更想知道我如何才能做到这一点。。。这是关于学习更多关于我如何做那样的事情。你知道我们大多数开发者都有好奇心。。。我只是想学习如何写我自己的shortcuts@MichaelGearhardt…很明显,您不想为此使用KeyValuePair、Dictionary或Tuple[]或其他任何东西。。所以,只要更新你的问题,不要使用任何明显的解决方案,并给出它们的列表。@MichaelGearhardt没关系。没有人知道什么对你来说是显而易见的,什么是不显而易见的,而你却不说。回答得好,但是对于devils advocate在我的帖子中关于更改枚举定义的-1的回应,我建议您明确定义一个case ComTypes.SMS,不要使用默认值,因为更改枚举定义同样会导致magic停止工作。我感到您的痛苦。我怀念其他语言中的这种简短表达。但我也觉得你的尝试根本不值得,除非你成功了,你会觉得很有趣。与其构建这样的操作符只是为了缩短几个表达式,不如聪明一点:完全删除表达式,因为它是一个常量键值映射,然后构建一个dictionary key:enum/value:string,并使用它以简单的result=dict[myenumval]方式进行查找。更容易、更快、更连贯、更易于编辑。DRY.switch是最接近的一款,不会给自己带来太多不便。如果你自己编写编译器,代码的可移植性就会被抛到窗外,因为没有其他人会拥有你的编译器,而常规的C编译器会显示出一大堆错误。使用新运算符获得更简洁的格式将新运算符引入具有编译器扩展的成熟语言将永远不会干净或简洁。这只会让其他人无法阅读你的代码。我感觉到了你的痛苦。我怀念其他语言中的这种简短表达。但我也觉得你的尝试根本不值得,除非你成功了,你会觉得很有趣。与其构建这样的操作符只是为了缩短几个表达式,不如聪明一点:完全删除表达式,因为它是一个常量键值映射,然后构建一个dictionary key:enum/value:string,并使用它以简单的result=dict[myenumval]方式进行查找。更容易、更快、更连贯、更易于编辑。DRY.switch是最接近的一款,不会给自己带来太多不便。如果你自己编写编译器,代码的可移植性就会被抛到窗外,因为没有其他人会拥有你的编译器,而常规的C编译器会显示出一大堆错误。使用新运算符获得更简洁的格式将新运算符引入具有编译器扩展的成熟语言将永远不会干净或简洁。这只会让其他人无法阅读你的代码。再说一遍,这不是关于其他可能的解决方案。。。我有工作代码,可以实现我需要的没有问题。。。这是关于我如何才能实现我在问题中提出的目标。同样,这不是关于其他可能的解决方案。。。我有工作代码,可以实现我需要的没有问题。。。这是关于我如何去实现我在问题中提出的目标
n、 -1表示枚举和标题数组之间的神奇连接。当有人更改ComTitles数组的顺序时,他/她必须记住正确的索引,以便与ComTypes枚举一起使用。枚举也是一样的。在这种情况下,依赖索引是一种非常糟糕的方法。@BurundukXP,从最佳实践的角度来看,我基本上同意;然而,如果枚举和数组被封装在一个类定义中——数组是私有的,并且是处理索引的公共属性,这是一种完全可用的方法。为什么要回退到enum is int battle?-1,以获得enum和标题数组之间的神奇连接。当有人更改ComTitles数组的顺序时,他/她必须记住正确的索引,以便与ComTypes enum一起使用。枚举也是一样的。在这种情况下,依赖索引是一种非常糟糕的方法。@BurundukXP,从最佳实践的角度来看,我基本上同意;然而,如果枚举和数组被封装在一个类定义中——数组是私有的,并且是处理索引的公共属性,这是一种完全可用的方法。为什么你想退回到enum is int battle?如果你需要更多的点,请问我?进一步的但我相信,只要搜索有关MSBuild的主题以及如何将自定义MSBuild任务添加到.csproj的主题,您就会找到所需的所有内容。csproj:一组非常棒的推荐解决方案!如果你需要更多的点,问我好吗?进一步的但我相信,只要搜索有关MSBuild的主题以及如何将自定义MSBuild任务添加到.csproj的主题,您就会找到所需的所有内容。csproj:一组非常棒的推荐解决方案!