开发的时候,经常被策划频繁变动的方案而苦恼。这时候就想要加入点动态语言来辅助一下。

在考虑用动态语言之前也曾想过使用动态加载dll的方式,实现基础接口来调用。在卸载的时候遇到了问题,虽可以通过应用程序域来绕过,但这又加入了应用程序域之间的交互。没有动态语言来的方便。

IronPython的官网:http://ironpython.codeplex.com/

在C#中使用IronPython

新建一个项目,ConsoleApplication

然后NuGet添加IronPython包

在Main函数中编写如下代码:

    ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = "print('Hello world!')";
var sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);

这里用到了三个主要类型:ScriptEngine, ScriptScope, ScriptSource

顾名思义ScriptEngine是引擎,ScriptScope相当于一个容器可用于传递一些自定义的变量,ScriptSource就是脚本源码。

运行后输出结果:Hello world!

C#向IronPython传递变量

将上面的代码修改如下

            ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = "print('Hello %d' %number)";
scope.SetVariable("number", );
ScriptSource sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);

输出结果变为:Hello 123

还可以试试更奇妙的,比如C#定义一个类

    public class Foo
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
}

传入这个变量试试,修改Main函数的代码

ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = @"print('Hello %s' %foo.Name)
foo.DoSth()";//注意这里换行是必须的
Foo foo = new Foo()
{
Name = "阿萨德",
Birthday = new DateTime(,,)
};
scope.SetVariable("foo", foo);
ScriptSource sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);

成功输出:Hello 阿萨德

那么如果调用Foo里的方法呢?可以哦,你可以试一试,还能够命中断点呢!

执行IronPython文件

将script字符串替换为文件路径,使用ScriptEngine的CreateScriptSourceFromFile方法可以执行文件格式的IronPython

新建文件,名为test.py, 将上面的script字符粘贴到文件内。修改文件的属性为“如果较新则复制”。

那么Main函数的代码段就是:

ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string path = @"test.py";
Foo foo = new Foo()
{
Name = "阿萨德",
Birthday = new DateTime(,,)
};
scope.SetVariable("foo", foo);
ScriptSource sourceCode = engine.CreateScriptSourceFromFile(path);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);

执行成功,输出结果不变。

但是此时编辑器对py文件的支持是木有的,此时可以安装一个插件,Python Tools for Visual Studio 简称PTVS,可以在GitHub上获取到:https://github.com/Microsoft/PTVS/releases

安装之后,就有了语法高亮和智能提示哦~

这个工具增加了很多对Python的支持,你还能在新建项目中看到新增的Python模板,包括了Django等一些流行的Python网站模板,当然IronPython的模板也是不可少的。

在IronPython中使用C#的类型

还有一个问题,刚才在foo中定义了Birthday这个属性,但是它的类型是DateTime,如何在IronPython中使用它呢?

修改test.py文件中的代码

print('Hello %s' %foo.Name)
foo.DoSth()
from System import DateTime
print("My birthday is %s" %foo.Birthday.ToString())

这里我使用了from System import DateTime这行语句就引入了DateTime的类型

同样的,你也可以引入System程序集中的String、TimeSpan等类型,方便得一塌糊涂,比如这样

from System import *

如果需要添加程序集引用呢?

比如我新建了一个类库,将Foo类放到了这个新的类库中,那么我要使用Foo的时候,只要这样:

import clr,sys
clr.AddReference('Foo')
from Foo import Foo foo = Foo()
foo.Name = "haha" print('Hello %s' %foo.Name)
from System import *
print("My birthday is %s" %foo.Birthday.ToString())

或许你的程序将告诉你一个找不到Module的错误,那就把Foo.dll拷贝到你的执行目录下。或者你也可以修改Main函数中的代码,使用engine.SetSearchPaths(new[]{@"../Foo/bin/Debug"});设置查找类库的路径。

如果报告无法在Foo中找到Foo类型,那就是你拷贝Foo类的代码到类库中去的时候没有使用Foo类库的namespace。

其他

现在已经知道了如何在C#中使用IronPython,以及在IronPython的代码中使用C#的类型和变量传递,那么就可以在你的C#程序中加入炫酷的脚本语言动态特性了。

关于CreateScriptSource的时机,你或许可以使用FileSystemWatcher类来监视文件修改,不过要注意多线程问题哦。

如果你并不需要在C#中加入IronPython,而仅仅只是想要用Python一样的语法来做一些.net的程序比如winform、wpf之类的,你可以安装IronPython的安装包,安装包在最上面给出的官网地址中有下载。安装之后将获得IronPython单独运行的环境和相关的文档。

然后你就可以通过PTVS帮你新增的几个IronPython项目模板来创建你的IronPython程序了。

而且,他们是支持断点调试的哦!你是不是有了好点子呢,比如在C#项目中使用Link文件来链接IronPython项目中的py文件,^_^

我已经迫不及待地想要写一个可以编辑脚本的小游戏来玩玩了呢。

最后加一个在GitHub上看到的IronPython的小游戏Sample

使用IronPython给.Net程序加点料的更多相关文章

  1. 使用IronPython给.Net程序

    使用IronPython给.Net程序加点料 开发的时候,经常被策划频繁变动的方案而苦恼.这时候就想要加入点动态语言来辅助一下. 在考虑用动态语言之前也曾想过使用动态加载dll的方式,实现基础接口来调 ...

  2. 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文

    阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...

  3. 使用Dynamics 365 CE Web API查询数据加点料及选项集字段常用查询

    微软动态CRM专家罗勇 ,回复336或者20190516可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me. 紧接上文:配置Postman通过OAuth 2 implicit ...

  4. Python装饰器-给你的咖啡加点料

    今天你的咖啡加糖了吗? 让我们通过一个简单的例子来引出装饰器的概念及用法.在引出装饰器之前,我们先来了解一下函数的概念. 一.函数回顾 1.在python中函数是一等公民,函数也是对象.我们可以把函数 ...

  5. 给你的移动网站加点料:推荐下载App,如果本地安装则直接打开本地App(Android/IOS)

    纵观现在每家移动网站,打开首页的时候,都有各种各样的形式来提示你下载自身的移动App(Android/IOS),这是做移动客户端产品的一个很好地引流的手段.当然各家引流下载的交互和视觉各不相同,有的是 ...

  6. linux c++应用程序内存高或者占用CPU高的解决方案_20161213

    对于绝大多数实时程序来说,实时处理相关程序中的循环问题所带来的对机器的损耗和自身的处理速度的平衡,以及与其他程序的交互以及对其他功能的影响难免会成为程序设计中最大的障碍同时也是最大的突破点. 在所有这 ...

  7. c++学习笔记---02---从一个小程序说起

    从一个小程序说起 这一讲的主要目的是帮助大家在C语言的背景知识上与C++建立联系. 问题探索 问题:对一个整型数组求和. 要求:定义一个存储着 n 个元素的数组,要求用C语言完成这个任务. 赶紧的:大 ...

  8. 快速开发微信小程序

    image.png 最近婷主在做微信小程序.自己的微信公众号也需要添加点料,乘着这次放假,把微信小程序研究了下.虽然没有做什么很强大的功能,不过好歹自己的公众号也有了微信小程序.够用即可. 1.需要先 ...

  9. 4 我们的第一个c#程序

    1.       控制台应用程序. 在我们这个培训中主要使用控制台应用程序来讲解知识点和做练习. 什么是控制台程序? 控制台程序运行在dos窗口.没有可视化的界面.可以通过Dos窗口进入输入和输出显示 ...

随机推荐

  1. 四元数(Quaternions)简介

    经常在代码中看到Quaternions,也知道它是用来表达三维空间的旋转的,但一直没有更深的理解.这两天终于花点时间看了看维基百科的介绍,算是多了解了点.做个记录吧! 本质上而言,四元数是一个数学概念 ...

  2. Servlet目录

    Servlet目录   课时1 Servlet概述12:30 课时2 servlet的第一个例子31:08 课时3 servlet的生命周期18:18 课时4 HttpServlet详细讲解31:43 ...

  3. Asp.Net MVC4入门指南(7):给电影表和模型添加新字段

    在本节中,您将使用Entity Framework Code First来实现模型类上的操作.从而使得这些操作和变更,可以应用到数据库中. 默认情况下,就像您在之前的教程中所作的那样,使用 Entit ...

  4. javascript eval和JSON之间的联系

    原出处:http://www.jb51.net/article/21688.htm eval函数的工作原理 eval函数会评估一个给定的含有JavaScript代码的字符串,并且试图去执行包含在字符串 ...

  5. Golang 文件服务器小结

    花了一个星期学习文件服务器,老是在一些地方搞混,整理一下所学的,清晰了不少. 学Go半个月,还有很多不懂的地方,有理解错误的,还望高手指出. 注:以下代码中,w为http.ResponseWriter ...

  6. 通过viewmodel找到view

    如何通过viewmodel找到view? 之前的做法是,在view加载时(Loaded),将view保存到viewmodel中,后来想想Caliburn-Micro,自带方法可以通过viewmodel ...

  7. js跨域访问

    什么是跨域 JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: 首 ...

  8. Being a Good Boy in Spring Festival 尼姆博弈

    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Descr ...

  9. javascript实现字符串的截取

    截取字符串方法有很多的,(不含根据传入参数截取成数组的split()方法)这里说的是子字符串,所以不说split()方法了. slice(),substr(),substring()一共三种方法,其中 ...

  10. Android应用第一次安装成功点击“打开”后Home键切出应用后再点击桌面图标返回导致应用重启问题

    最近项目中遇到一个问题,用户第一次安装应用在系统的安装器安装完成界面有“完成”和“打开”两个按钮. 当用户点击“打开”按钮进入用户注册页面进行手机号验证码发送和验证码输入等操作界面,若此时用户点击Ho ...