Tag: metaprogramming

如何编写其逻辑受到保护以防止未来其他枚举的代码?

我很难描述这个问题。 也许这就是为什么我很难找到一个好的解决方案(这些话只是不合作)。 让我通过代码解释: // original code enum Fruit { Apple, Orange, Banana, } … Fruit fruit = acquireFruit(); if (fruit != Fruit.Orange && fruit != Fruit.Banana) coreFruit(); else pealFruit(); eatFruit(); 现在假装多年的发展与这三种类型。 上述逻辑的不同风格在存储过程,SSIS包,Windows应用程序,Web应用程序,Java应用程序,perl脚本等中传播…. 最后: // new code enum Fruit { Apple, Orange, Banana, Grape, } 大多数时候,“系统”运行正常,直到使用Grapes。 然后,当不需要或不需要时,系统的某些部分会不恰当地起作用,剥离和/或取芯葡萄。 你坚持什么样的指导方针,以避免这些混乱? 我的偏好是旧代码如果没有重构以考虑新的枚举,则抛出exception。 我在黑暗中想出了一个镜头: #1避免像这样“不在逻辑中” // select fruit that needs […]

使用Roslyn在引用的程序集中获取接口实现

我想在我正在开发的框架中绕过一些经典的汇编扫描技术。 所以,说我已经定义了以下合同: public interface IModule { } 这存在于Contracts.dll 。 现在,如果我想发现这个接口的所有实现,我们可能会做类似于以下的事情: public IEnumerable DiscoverModules() { var contractType = typeof(IModule); var assemblies = AppDomain.Current.GetAssemblies() // Bad but will do var types = assemblies .SelectMany(a => a.GetExportedTypes) .Where(t => contractType.IsAssignableFrom(t)) .ToList(); return types.Select(t => Activator.CreateInstance(t)); } 不是一个很好的例子,但它会做。 现在,这些类型的汇编扫描技术可能完全不足,而且它们都在运行时完成,通常会影响启动性能。 在新的DNX环境中,我们可以使用ICompileModule实例作为元编程工具,因此您可以将ICompileModule的实现ICompileModule到项目的Compiler\Preprocess文件夹中,并让它做一些时髦的事情。 我的目标是使用ICompileModule实现,以便在编译时执行我们在运行时所做的工作。 在我的引用(包括编译和程序集)和我当前的编译中,发现所有可以实现的IModule实例 创建一个类,让我们称之为ModuleList ,其实现产生每个模块的实例。 public static class ModuleList { […]

如何使用IL改变盒装结构

想象一下,我们有一个可变的struct (是的,不要开始): public struct MutableStruct { public int Foo { get; set; } public override string ToString() { return Foo.ToString(); } } 使用reflection,我们可以获取此struct的盒装实例并在框内变异: // this is basically what we want to emulate object obj = new MutableStruct { Foo = 123 }; obj.GetType().GetProperty(“Foo”).SetValue(obj, 456); System.Console.WriteLine(obj); // “456” 我想做的是写一些可以做到这一点的IL – 但速度更快。 我是一个元编程迷; p 取消任何一个值并使用常规IL来改变值是微不足道的 – 但是你不能只是在之后调用它,因为这将创建一个不同的框。 […]

我可以使用Roslyn进行编译时代码重写吗?

比如我有 class Foo: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public int Bar {get;set;} } 我可以在编译时获取Foo类AST并重写Bar public string Bar { get { return this.bar; } set { if (value != this.bar) { this.phoneNumberValue = value; PropertyChanged(this, new PropertyChangedEventArgs(“Bar”)); } } } 。