如何使用默认构造函数创建记录类
结构有默认构造函数,就像我这样做一样,
type tagONEDEV_FlowRec =
struct
.......
end
我可以执行 new DeviceModel.tagONEDEV_FlowRec()
但它不适用于此:
let (<++|) device bytes size =
let unmanagedPtr = Marshal.AllocHGlobal(size : int)
Marshal.Copy( (bytes : byte array), 0, unmanagedPtr, size)
Marshal.PtrToStructure(unmanagedPtr, (device : obj)) // Here
Marshal.FreeHGlobal(unmanagedPtr)
我在这里需要一个类似的记录类
[<type:StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)>]
type tagONEDEV_FlowRec = {
mutable ....;}
,或者
type tagONEDEV_FlowRec =
class
.......
end
但这里没有默认构造函数和结构非常大到零手动初始化它们,那么我如何将此类与默认构造函数一起使用?
如果我找不到解决方案,我认为在 C# 甚至 VB.NET 上重新编码这部分对我来说会更快。听起来很像拐杖解决方案,但看起来我还无法使用 F# OOP 部分进行拨号。
另外:我不想输入的是:
{TimeRec = 0;
Num = 0us;
FlagErr = 0us;
C6 = 0.0;
C2H6 = 0.0;
C3H8 = 0.0;
CH4 = 0.0;
CO2 = 0.0;
iC4H10 = 0.0;
iC5H12 = 0.0;
neoC5H12 = 0.0;
N2 = 0.0;
nC5H12 = 0.0;
O2 = 0.0;
nC4H10 = 0.0;
He = 0.0;
H2 = 0.0;
H2O = 0.0;
id = 0us; }
<-这是我默认想要的,因为我有更大的结构,并且编写这样的构造函数是邪恶的。
structures got default constructors like if I do
type tagONEDEV_FlowRec =
struct
.......
end
I can do new DeviceModel.tagONEDEV_FlowRec()
but it doesn't work with this :
let (<++|) device bytes size =
let unmanagedPtr = Marshal.AllocHGlobal(size : int)
Marshal.Copy( (bytes : byte array), 0, unmanagedPtr, size)
Marshal.PtrToStructure(unmanagedPtr, (device : obj)) // Here
Marshal.FreeHGlobal(unmanagedPtr)
I need a record class here alike
[<type:StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)>]
type tagONEDEV_FlowRec = {
mutable ....;}
or
type tagONEDEV_FlowRec =
class
.......
end
but there is no default constructor here and structures is very big to zero init them manually, so how can I use such classes with default constructors ?
If I will not find the solution I think that will be faster for me to recode this part on C# or even on VB.NET. Sounds alike crutch-solution but looking like I can't dial with F# OOP part yet.
an addition: the thing I don't want to type is :
{TimeRec = 0;
Num = 0us;
FlagErr = 0us;
C6 = 0.0;
C2H6 = 0.0;
C3H8 = 0.0;
CH4 = 0.0;
CO2 = 0.0;
iC4H10 = 0.0;
iC5H12 = 0.0;
neoC5H12 = 0.0;
N2 = 0.0;
nC5H12 = 0.0;
O2 = 0.0;
nC4H10 = 0.0;
He = 0.0;
H2 = 0.0;
H2O = 0.0;
id = 0us; }
<- that is what I want to have by default, because I've got much lager structures then this and writing such constuctors is wicked.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
看来我找到了一个有效的技巧:
Seems like I found a working trick :
如果您出于某种原因确实想要初始化一条记录,正如约翰所说,有
“黑客解决方案”。
这是我的:(我同意如果你必须这样做,你可能做错了,但我向你保证我的确实对我所做的事情有帮助:)。
这里是你将如何使用它:
结果将如下所示:
{字符串=空;整数=0; A = {字符串= null;整数=0; StringOption = null;};}
If you for some reason really do want to initialize a record, as John said, there are
"hackish solution"s.
Here is mine: (I agree with if you have to do this, you probably are doing it wrong, but i assure you mine really helped for what i was doing :).
End here is how you would use it:
And the result would look like this:
{String = null; Int = 0; A = {String = null; Int = 0; StringOption = null;};}
正如 jpalmer 试图解释必须使用参数初始化记录一样。我认为您应该尝试使用
此处查看: MSDN Docs Explicit字段
是的,我知道有更多的代码行和额外的“struct”、“end”和一些“val”,但这真的这么难吗?如果您的类型使用了 1000 个属性,无论如何您都应该重新考虑您的代码。
as jpalmer tried to explain a record has to be initialized with the parameters. I think you should try to use
see here: MSDN Docs Explicit Fields
yeah I know there are more lines of code and an additional "struct", "end" and some "val"s but is this really this hard? If you are using 1000 properties on your type you should rethink your code anyhow.
在 F# 中,您可以使用隐式语法放置默认构造函数,就像
我认为您使用
record
的方式有点奇怪,在 F# 中,记录类似于具有命名成员的元组 - http://msdn.microsoft.com/en-us/library/dd233184.aspx编辑
所以问题基本上是你是否可以有一个将 a 归零的构造函数记录类型 - 回答否。在这种情况下,我认为最好的答案是从记录切换到结构/类,以便您可以获得所需的行为。
我想到的一种黑客解决方案是使用 System.Reflection.Assembly.CreateInstance ,它有时可以帮助解决此类问题,但编译器不提供默认构造函数,因此它不起作用
In F# you can put a default constructor using implicit syntax like
I think you are using
record
in a way which is a bit odd, in F# a record is similar to a tuple with named members - http://msdn.microsoft.com/en-us/library/dd233184.aspxEDIT
So the question is basically can you have a constructor which zeroes a record type - answer no. In this case I think the best answer is to switch from a record to a struct / class so that you can get the behaviour you want.
One hackish solution that I thought of was to use
System.Reflection.Assembly.CreateInstance
which can sometimes help with things like this, but the compiler provides no default constructor so it doesn't work使用 CLIMutable 声明带有隐式默认构造函数的记录。
为了防止代码漂移,我推荐使用以下样式来代替上面的样式。
“代码漂移”是指诸如属性之类的内容在没有人注意到的情况下偏离其最初预期的代码元素的趋势。使用第二种样式,由于编辑时的粗心,属性更不可能偏离声明。
Use CLIMutable to declare a record with an implicit default constructor.
In order to prevent code drift, I recommend the following style in favor of the above.
"Code drift" is the tendency for stuff like attributes to drift away from the code element for which it was originally intended, without anyone noticing it. With the second style, it is more unlikely that the attribute will drift away from the declaration due to carelessness while editing.