在Maxscript中创建.Net类型

调用一个.net对象

在mxs中,使用dotNetClass可以访问一个实例类、静态类、枚举、结构体...他关联的是类型的静态成员
使用dotNetObject可以new一个实例对象

在vs中,我们看到MessageBox这个类的完全体

MessageBox的Show方法是一个静态成员,为什么呢,如果你完全不会c#,那么你只需要看他是不是用他的类名直接调用方法/属性就行

mb = dotNetClass "System.Windows.Forms.MessageBox"

使用mxs的方式调用函数

mb.Show "你好max"

"你好max" 是一个mxs内的字符串,他可以与 public static DialogResult Show(string text); 中参数的string类型通用
在maxscript与.net的交互中,普通的基础类型可以直接传递,至少大部分情况下是通用的

也可以直接传递 .net string 对象作为参数

netString = dotNetObject "System.String" "你好max.net"
mb.Show netString 

创建一个.net对象

在c#中string的创建形式为

上面是使用关键字的方法创建,看起来很美好,但并不便于转换理解
我们可以把它变成原始的方式

在mxs中就是这样

netString = dotNetObject "System.String" "你好"

dotNetObject : new
"System.String" :需要创建的具体类型全程
"你好": 构造函数的第一个参数,如果有第二个参数,跟着往后面接

在创建一个比较好理解的类型


至于在mxs里为啥不能直接使用无构造函数的方式,不得而知

创建一个数组

mxsArr =  #(1,2,3,4)
Int32Type = dotNetClass "System.Int32[]"
Int32Array = dotnet.ValueToDotNetObject Arr Int32Type

ValueToDotNetObject 可以将mxs的数据类型转换到.net的数据类型
https://trykle.gitee.io/3dsmax-2020.1-maxscript-help/?query=dotNet.ValueToDotNetObject#!/url=./files/GUID-FB52FDC5-CC83-46FB-A430-B90E7107805A.htm
如果你是用的泛型List<>,那么他应该与下方的泛型创建方法雷同

创建一个泛型

c#里字典的创建形式

在mxs里长这样

老实说,我并不知道这样写的规则出处在哪

但我通过ILSPY能看到一些类似的语法

`后面的数字表示泛型参数个数
string int 换成具体的类型
<>换成[]

创建一个可空int


编译之后在ILSPY中切到c#的远古版本,他长这样

IL中他长这样

结合上面的泛型规则,他在mxs里长这样

再来看一个调用方法的例子


第一步先找到这个方法

GetFolderPath = (dotNetClass "System.Environment").GetFolderPath

第二步创建参数,参数是个枚举类型

在此翻车了,我们无法找到这个类型

我们来验证一下枚举类型的创建方法,找到一个其他的枚举类型


说明这样是没有错的
转到IL中,他们分别变成了这样,System.Environment后面变成了/

把/变成+,正常列出 (至于为什么要把/变成+,不得而知)

最后调用方法

using

using 是c#的一个语法糖,它将在离开方法前为你自动释放资源

using (Class1 cls1 = new Class1())
{
  // the code using cls1
} // call the Dispose on cls1

改变成正常c#语法为

Class1 cls1 = new Class1();
//使用 ...
cls1.Dispose();

最后关于不得而知的类型创建字符串

这与c#的反射创建类型是一致的
https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.createinstance?view=net-5.0
通过GetType可以获取到完整名字
好你已经发现了 dotNetObject 和 dotNetClass 这2个关键字的秘密,他就是反射的包装器

将非标准类型的值传入dotnet

myBtn = dotNetObject "System.Windows.Forms.Button"


--可互相转换的类型
myBtn.Width = 100
myBtn.Width = "一百" -- 无法转换: "一百" 到类型: Integer

--object类型
myBtn.Tag = 1
classof myBtn.Tag --Integer

myBtn.Tag = "123"
classof myBtn.Tag --String

-- 非可互相转换的类型
myBox = box()
myBtn.Tag = myBox -- 无法转换: $Box:Box001 @ [0.000000,0.000000,0.000000] 到类型: System.Object

--转换为 dotNetMXSValue,此参数类型object可以传递
myBoxNet = dotNetMXSValue myBox
myBtn.Tag = myBoxNet
classof myBtn.Tag --dotNetMXSValue
-- 通过.Value取值
classof myBtn.Tag.Value -- Box
posted @ 2021-09-24 11:38  trykle  阅读(450)  评论(0编辑  收藏  举报