将 #if/#endif 指令添加到生成类的 CodeTypeDefinition 上的 DataContract 属性

发布于 2024-12-02 05:40:33 字数 432 浏览 2 评论 0 原文

我正在使用 XSD -> C# 类解析器为我们的数据模型生成类,该数据模型将在 WPF 客户端和 Silverlight 基于 Web 的部分之间共享。

我们正在尝试使用 [DataContract] 属性来增强生成的类,这些属性仅在未定义 SILVERLIGHT 符号时使用,即:

#if !SILVERLIGHT
[DataContract]
#endif
public class Class1 { /* ... */ }

如何将此 #if / #endif 块添加到 Class1 的 >CodeTypeDefinition,还是 DataContractCodeAttributeDeclaration

I'm working with an XSD -> C# class parser which generates classes for our data model, which is to be shared between a WPF client and a Silverlight web-based portion.

We are trying to augment the generated classes with [DataContract] attributes that should only be used when the SILVERLIGHT symbol is not defined, i.e.:

#if !SILVERLIGHT
[DataContract]
#endif
public class Class1 { /* ... */ }

How can I add this #if / #endif block to the CodeTypeDefinition of the Class1, or to the CodeAttributeDeclaration of DataContract?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾`听者〃 2024-12-09 05:40:33

不确定如何获取 #if 的发出,但您可以生成该类的两个不同版本(一种具有 DataContract 属性,一种不具有)并使用 ConditionalAttribute (http://msdn.microsoft.com/en-us/library/ system.diagnostics.conditionalattribute.aspx) 以便为每个环境使用正确的一个

  CodeAttributeDeclaration declaration1 =
    new CodeAttributeDeclaration(
      "System.Diagnostics.ConditionalAttribute",
      new CodeAttributeArgument(
        new CodePrimitiveExpression("SILVERLIGHT")));

Not sure how to get #if's emitted but you could instead generate two different versions of the class (one with the DataContract attribute, one without) and use a ConditionalAttribute (http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx) on them so the correct one is used for each environment

  CodeAttributeDeclaration declaration1 =
    new CodeAttributeDeclaration(
      "System.Diagnostics.ConditionalAttribute",
      new CodeAttributeArgument(
        new CodePrimitiveExpression("SILVERLIGHT")));
踏月而来 2024-12-09 05:40:33

我实际上决定做的是在生成代码文件后通过 Python 脚本添加 #if / #endif 标记。罗伯特的回复在功能上是有效的,但我只是觉得使用两个单独的类是不对的,而一个应该就可以了。

尽管它在数据模型生成中引入了另一种语言,但这似乎是获得我想要的东西的最干净的方法。我们正在使用的脚本如下。由于我们采用了新的方式构建数据契约,现在只需要检查 NonSerialized 属性(特别是在 PropertyChanged 事件上)。

#!/usr/bin/env python

import sys
from optparse import OptionParser
import shutil

# Use OptionParser to parse script arguments.
parser = OptionParser()

# Filename argument.
parser.add_option("-f", "--file", action="store", type="string", dest="filename", help="C# class file to parse", metavar="FILE.cs")

# Parse the arguments to the script.
(options, args) = parser.parse_args()

# The two files to be used: the original and a backup copy.
filename = options.filename

# Read the contents of the file.
f = open( filename, 'r' )
csFile = f.read()
f.close()

# Add #if tags to the NonSerialized attributes.
csFile = csFile.replace('        [field: NonSerialized()]',
                    '        #if !SILVERLIGHT\r\n        [field: NonSerialized()]\r\n        #endif')

# Rewrite the file contents.
f = open( filename, 'r' )
f.write(csFile)
f.close()

What I've actually decided to do is add the #if / #endif tags through a Python script, after the code file is generated. Robert's reply is functionally valid, but I just didn't feel right using two separate classes when one should be just fine.

Although it introduces another language into the data model generation, this seems like the cleanest way to get exactly what I want. The script we are using is below. It only needs to check for NonSerializable attributes (specifically, on PropertyChanged events) now because of a new way we structured the data contract.

#!/usr/bin/env python

import sys
from optparse import OptionParser
import shutil

# Use OptionParser to parse script arguments.
parser = OptionParser()

# Filename argument.
parser.add_option("-f", "--file", action="store", type="string", dest="filename", help="C# class file to parse", metavar="FILE.cs")

# Parse the arguments to the script.
(options, args) = parser.parse_args()

# The two files to be used: the original and a backup copy.
filename = options.filename

# Read the contents of the file.
f = open( filename, 'r' )
csFile = f.read()
f.close()

# Add #if tags to the NonSerialized attributes.
csFile = csFile.replace('        [field: NonSerialized()]',
                    '        #if !SILVERLIGHT\r\n        [field: NonSerialized()]\r\n        #endif')

# Rewrite the file contents.
f = open( filename, 'r' )
f.write(csFile)
f.close()
够运 2024-12-09 05:40:33

我不建议在生成的类上添加 [DataContract] 属性,因为重新生成类时它会被覆盖。如果我是您,我会考虑使用方法 罗伯特·利维解释道。

您可以使用 AutoMapper 帮助您将模型映射到 DTO。

I wouldn't suggest adding the [DataContract] attribute on a generated class, since it will be overwritten when the class will be regenerated. If I were you, I would consider mapping your data model into DTOs (data transfer object) that will have the [DataContract] attribute using the method Robert Levy explained.

You can use AutoMapper to help you map your model to your DTOs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文