草庐IT

c# - XmlCodeExporter 和可为 null 的类型

coder 2024-05-21 原文

System.Xml.Serialization.XmlCodeExporter从 XSD 架构生成代码(以代码 CodeDom 形式)。但它有一些怪癖。例如一个可选元素:

<xs:element name="Something" type="xs:decimal" minOccurs="0" maxOccurs="1"/>

我希望这会生成一个类型为 Nullable<decimal> 的相应代码成员, 但它实际上创建了一个 decimal 类型的成员, 然后是一个单独的 SomethingSpecified应单独切换以指示空值的字段。这可能是因为该库是在引入可空类型之前创建的,但它导致代码非常不方便。

是否可以调整此代码生成,或者是否有替代工具可以在这种情况下生成更好的代码?

编辑:我知道我可以修改架构并添加 nillable='true' ,但我不想更改架构来解决代码生成的限制。

最佳答案

文章 Writing your own XSD.exe Mike Hadlow 的 提供了一个基本框架,用于创建您自己的 xsd.exe 版本.它有以下步骤:

  1. 使用 XmlSchema.Read() 导入模式和 XmlSchemaImporter .

  2. 使用 XmlCodeExporter 生成要创建的 .Net 类型和属性.

  3. 根据需要调整生成的类型和属性

    在这里您可能想要删除生成的 xxxSpecified属性并将其对应的“真实”属性提升为可为空。

  4. 使用 CSharpCodeProvider 生成最终代码.

使用此框架,并通过实验确定 XmlCodeExporter 实际生成的类型使用调试器,我创建了以下 CustomXsdCodeGenerator :

public class CustomXsdCodeGenerator : CustomXsdCodeGeneratorBase
{
    readonly bool promoteToNullable;

    public CustomXsdCodeGenerator(string Namespace, bool promoteToNullable) : base(Namespace)
    {
        this.promoteToNullable = promoteToNullable;
    }

    protected override void ModifyGeneratedCodeTypeDeclaration(CodeTypeDeclaration codeType, CodeNamespace codeNamespace)
    {
        RemoveSpecifiedProperties(codeNamespace, promoteToNullable);
        base.ModifyGeneratedCodeTypeDeclaration(codeType, codeNamespace);
    }

    private static void RemoveSpecifiedProperties(CodeNamespace codeNamespace, bool promoteToNullable)
    {
        foreach (CodeTypeDeclaration codeType in codeNamespace.Types)
        {
            RemoveSpecifiedProperties(codeType, codeNamespace, promoteToNullable);
        }
    }

    private static void RemoveSpecifiedProperties(CodeTypeDeclaration codeType, CodeNamespace codeNamespace, bool promoteToNullable)
    {
        var toRemove = new List<CodeTypeMember>();

        foreach (var property in codeType.Members.OfType<CodeMemberProperty>())
        {
            CodeMemberField backingField;
            CodeMemberProperty specifiedProperty;
            if (!property.TryGetBackingFieldAndSpecifiedProperty(codeType, out backingField, out specifiedProperty))
                continue;
            var specifiedField = specifiedProperty.GetBackingField(codeType);
            if (specifiedField == null)
                continue;
            toRemove.Add(specifiedProperty);
            toRemove.Add(specifiedField);

            if (promoteToNullable)
            {
                // Do not do this for attributes
                if (property.CustomAttributes.Cast<CodeAttributeDeclaration>().Any(a => a.AttributeType.BaseType == typeof(System.Xml.Serialization.XmlAttributeAttribute).FullName))
                    continue;
                var typeRef = property.Type;
                if (typeRef.ArrayRank > 0)
                    // An array - not a reference type.
                    continue;

                // OK, two possibilities here:
                // 1) The property might reference some system type such as DateTime or decimal
                // 2) The property might reference some type being defined such as an enum or struct.

                var type = Type.GetType(typeRef.BaseType);
                if (type != null)
                {
                    if (!type.IsClass)
                    {
                        if (type == typeof(Nullable<>))
                            // Already nullable
                            continue;
                        else if (!type.IsGenericTypeDefinition && (type.IsValueType || type.IsEnum) && Nullable.GetUnderlyingType(type) == null)
                        {
                            var nullableType = typeof(Nullable<>).MakeGenericType(type);
                            var newRefType = new CodeTypeReference(nullableType);
                            property.Type = newRefType;
                            backingField.Type = newRefType;
                        }
                    }
                }
                else
                {
                    var generatedType = codeNamespace.FindCodeType(typeRef);
                    if (generatedType != null)
                    {
                        if (generatedType.IsStruct || generatedType.IsEnum)
                        {
                            var newRefType = new CodeTypeReference(typeof(Nullable<>).FullName, typeRef);
                            property.Type = newRefType;
                            backingField.Type = newRefType;
                        }
                    }
                }
            }
        }
        foreach (var member in toRemove)
        {
            codeType.Members.Remove(member);
        }
    }
}

public static class CodeNamespaceExtensions
{
    public static CodeTypeDeclaration FindCodeType(this CodeNamespace codeNamespace, CodeTypeReference reference)
    {
        if (codeNamespace == null)
            throw new ArgumentNullException();
        if (reference == null)
            return null;
        CodeTypeDeclaration foundType = null;
        foreach (CodeTypeDeclaration codeType in codeNamespace.Types)
        {
            if (codeType.Name == reference.BaseType)
            {
                if (foundType == null)
                    foundType = codeType;
                else if (foundType != codeType)
                {
                    foundType = null;
                    break;
                }
            }
        }
        return foundType;
    }
}

public static class CodeMemberPropertyExtensions
{
    public static bool TryGetBackingFieldAndSpecifiedProperty(this CodeMemberProperty property, CodeTypeDeclaration codeType,
        out CodeMemberField backingField, out CodeMemberProperty specifiedProperty)
    {
        if (property == null)
        {
            backingField = null;
            specifiedProperty = null;
            return false;
        }

        if ((backingField = property.GetBackingField(codeType)) == null)
        {
            specifiedProperty = null;
            return false;
        }

        specifiedProperty = null;
        var specifiedName = property.Name + "Specified";
        foreach (var p in codeType.Members.OfType<CodeMemberProperty>())
        {
            if (p.Name == specifiedName)
            {
                // Make sure the property is marked as XmlIgnore (there might be a legitimate, serializable property
                // named xxxSpecified).
                if (!p.CustomAttributes.Cast<CodeAttributeDeclaration>().Any(a => a.AttributeType.BaseType == typeof(System.Xml.Serialization.XmlIgnoreAttribute).FullName))
                    continue;
                if (specifiedProperty == null)
                    specifiedProperty = p;
                else if (specifiedProperty != p)
                {
                    specifiedProperty = null;
                    break;
                }
            }
        }
        if (specifiedProperty == null)
            return false;
        if (specifiedProperty.GetBackingField(codeType) == null)
            return false;
        return true;
    }

    public static CodeMemberField GetBackingField(this CodeMemberProperty property, CodeTypeDeclaration codeType)
    {
        if (property == null)
            return null;

        CodeMemberField returnedField = null;
        foreach (var statement in property.GetStatements.OfType<CodeMethodReturnStatement>())
        {
            var expression = statement.Expression as CodeFieldReferenceExpression;
            if (expression == null)
                return null;
            if (!(expression.TargetObject is CodeThisReferenceExpression))
                return null;
            var fieldName = expression.FieldName;
            foreach (var field in codeType.Members.OfType<CodeMemberField>())
            {
                if (field.Name == fieldName)
                {
                    if (returnedField == null)
                        returnedField = field;
                    else if (returnedField != field)
                        return null;
                }
            }
        }

        return returnedField;
    }
}

public abstract class CustomXsdCodeGeneratorBase
{
    // This base class adapted from http://mikehadlow.blogspot.com/2007/01/writing-your-own-xsdexe.html

    readonly string Namespace;

    public CustomXsdCodeGeneratorBase(string Namespace)
    {
        this.Namespace = Namespace;
    }

    public void XsdToClassTest(IEnumerable<string> xsds, TextWriter codeWriter)
    {
        XsdToClassTest(xsds.Select(xsd => (Func<TextReader>)(() => new StringReader(xsd))), codeWriter);
    }

    public void XsdToClassTest(IEnumerable<Func<TextReader>> xsds, TextWriter codeWriter)
    {
        var schemas = new XmlSchemas();

        foreach (var getReader in xsds)
        {
            using (var reader = getReader())
            {
                var xsd = XmlSchema.Read(reader, null);
                schemas.Add(xsd);
            }
        }

        schemas.Compile(null, true);
        var schemaImporter = new XmlSchemaImporter(schemas);

        var maps = new List<XmlTypeMapping>();
        foreach (XmlSchema xsd in schemas)
        {
            foreach (XmlSchemaType schemaType in xsd.SchemaTypes.Values)
            {
                maps.Add(schemaImporter.ImportSchemaType(schemaType.QualifiedName));
            }
            foreach (XmlSchemaElement schemaElement in xsd.Elements.Values)
            {
                maps.Add(schemaImporter.ImportTypeMapping(schemaElement.QualifiedName));
            }
        }

        // create the codedom
        var codeNamespace = new CodeNamespace(this.Namespace);
        var codeExporter = new XmlCodeExporter(codeNamespace);
        foreach (XmlTypeMapping map in maps)
        {
            codeExporter.ExportTypeMapping(map);
        }

        ModifyGeneratedNamespace(codeNamespace);

        // Check for invalid characters in identifiers
        CodeGenerator.ValidateIdentifiers(codeNamespace);

        // output the C# code
        var codeProvider = new CSharpCodeProvider();
        codeProvider.GenerateCodeFromNamespace(codeNamespace, codeWriter, new CodeGeneratorOptions());
    }

    protected virtual void ModifyGeneratedNamespace(CodeNamespace codeNamespace)
    {
        foreach (CodeTypeDeclaration codeType in codeNamespace.Types)
        {
            ModifyGeneratedCodeTypeDeclaration(codeType, codeNamespace);
        }
    }

    protected virtual void ModifyGeneratedCodeTypeDeclaration(CodeTypeDeclaration codeType, CodeNamespace codeNamespace)
    {
    }
}

为了测试它,我创建了以下类型:

namespace SampleClasses
{
    public class SimleSampleClass
    {
        [XmlElement]
        public decimal Something { get; set; }

        [XmlIgnore]
        public bool SomethingSpecified { get; set; }
    }

    [XmlRoot("RootClass")]
    public class RootClass
    {
        [XmlArray]
        [XmlArrayItem("SampleClass")]
        public List<SampleClass> SampleClasses { get; set; }
    }

    [XmlRoot("SampleClass")]
    public class SampleClass
    {
        [XmlAttribute]
        public long Id { get; set; }

        public decimal Something { get; set; }

        [XmlIgnore]
        public bool SomethingSpecified { get; set; }

        public SomeEnum SomeEnum { get; set; }

        [XmlIgnore]
        public bool SomeEnumSpecified { get; set; }

        public string SomeString { get; set; }

        [XmlIgnore]
        public bool SomeStringSpecified { get; set; }

        public decimal? SomeNullable { get; set; }

        [XmlIgnore]
        public bool SomeNullableSpecified { get; set; }

        public DateTime SomeDateTime { get; set; }

        [XmlIgnore]
        public bool SomeDateTimeSpecified { get; set; }

        // https://stackoverflow.com/questions/3280362/most-elegant-xml-serialization-of-color-structure

        [XmlElement(Type = typeof(XmlColor))]
        public Color MyColor { get; set; }

        [XmlIgnore]
        public bool MyColorSpecified { get; set; }
    }

    public enum SomeEnum
    {
        DefaultValue,
        FirstValue,
        SecondValue,
        ThirdValue,
    }

    // https://stackoverflow.com/questions/3280362/most-elegant-xml-serialization-of-color-structure
    public struct XmlColor
    {
        private Color? color_;

        private Color Color
        {
            get
            {
                return color_ ?? Color.Black;
            }
            set
            {
                color_ = value;
            }
        }

        public XmlColor(Color c) { color_ = c; }

        public Color ToColor()
        {
            return Color;
        }

        public void FromColor(Color c)
        {
            Color = c;
        }

        public static implicit operator Color(XmlColor x)
        {
            return x.ToColor();
        }

        public static implicit operator XmlColor(Color c)
        {
            return new XmlColor(c);
        }

        [XmlAttribute]
        public string Web
        {
            get { return ColorTranslator.ToHtml(Color); }
            set
            {
                try
                {
                    if (Alpha == 0xFF) // preserve named color value if possible
                        Color = ColorTranslator.FromHtml(value);
                    else
                        Color = Color.FromArgb(Alpha, ColorTranslator.FromHtml(value));
                }
                catch (Exception)
                {
                    Color = Color.Black;
                }
            }
        }

        [XmlAttribute]
        public byte Alpha
        {
            get { return Color.A; }
            set
            {
                if (value != Color.A) // avoid hammering named color if no alpha change
                    Color = Color.FromArgb(value, Color);
            }
        }

        public bool ShouldSerializeAlpha() { return Alpha < 0xFF; }
    }
}

使用通用 xsd.exe我从中生成了以下架构:

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="SimleSampleClass" nillable="true" type="SimleSampleClass" />
  <xs:complexType name="SimleSampleClass">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="Something" type="xs:decimal" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="RootClass" nillable="true" type="RootClass" />
  <xs:complexType name="RootClass">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="SampleClasses" type="ArrayOfSampleClass" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ArrayOfSampleClass">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="SampleClass" nillable="true" type="SampleClass" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="SampleClass">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="Something" type="xs:decimal" />
      <xs:element minOccurs="0" maxOccurs="1" name="SomeEnum" type="SomeEnum" />
      <xs:element minOccurs="0" maxOccurs="1" name="SomeString" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="SomeNullable" nillable="true" type="xs:decimal" />
      <xs:element minOccurs="0" maxOccurs="1" name="SomeDateTime" type="xs:dateTime" />
      <xs:element minOccurs="0" maxOccurs="1" name="MyColor" type="XmlColor" />
    </xs:sequence>
    <xs:attribute name="Id" type="xs:long" use="required" />
  </xs:complexType>
  <xs:simpleType name="SomeEnum">
    <xs:restriction base="xs:string">
      <xs:enumeration value="DefaultValue" />
      <xs:enumeration value="FirstValue" />
      <xs:enumeration value="SecondValue" />
      <xs:enumeration value="ThirdValue" />
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="XmlColor">
    <xs:attribute name="Web" type="xs:string" />
    <xs:attribute name="Alpha" type="xs:unsignedByte" />
  </xs:complexType>
  <xs:element name="SampleClass" nillable="true" type="SampleClass" />
  <xs:element name="SomeEnum" type="SomeEnum" />
  <xs:element name="XmlColor" type="XmlColor" />
</xs:schema>

并且,使用此架构,我使用 CustomXsdCodeGenerator 重新生成了以下 C# 类与 promoteToNullable = trueNamespace = "Question42295155" :

namespace Question42295155 {


    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
    public partial class SimleSampleClass {

        private System.Nullable<decimal> somethingField;

        /// <remarks/>
        public System.Nullable<decimal> Something {
            get {
                return this.somethingField;
            }
            set {
                this.somethingField = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
    public partial class SampleClass {

        private System.Nullable<decimal> somethingField;

        private System.Nullable<SomeEnum> someEnumField;

        private string someStringField;

        private System.Nullable<decimal> someNullableField;

        private System.Nullable<System.DateTime> someDateTimeField;

        private XmlColor myColorField;

        private long idField;

        /// <remarks/>
        public System.Nullable<decimal> Something {
            get {
                return this.somethingField;
            }
            set {
                this.somethingField = value;
            }
        }

        /// <remarks/>
        public System.Nullable<SomeEnum> SomeEnum {
            get {
                return this.someEnumField;
            }
            set {
                this.someEnumField = value;
            }
        }

        /// <remarks/>
        public string SomeString {
            get {
                return this.someStringField;
            }
            set {
                this.someStringField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
        public System.Nullable<decimal> SomeNullable {
            get {
                return this.someNullableField;
            }
            set {
                this.someNullableField = value;
            }
        }

        /// <remarks/>
        public System.Nullable<System.DateTime> SomeDateTime {
            get {
                return this.someDateTimeField;
            }
            set {
                this.someDateTimeField = value;
            }
        }

        /// <remarks/>
        public XmlColor MyColor {
            get {
                return this.myColorField;
            }
            set {
                this.myColorField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public long Id {
            get {
                return this.idField;
            }
            set {
                this.idField = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")]
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
    public enum SomeEnum {

        /// <remarks/>
        DefaultValue,

        /// <remarks/>
        FirstValue,

        /// <remarks/>
        SecondValue,

        /// <remarks/>
        ThirdValue,
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
    public partial class XmlColor {

        private string webField;

        private byte alphaField;

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string Web {
            get {
                return this.webField;
            }
            set {
                this.webField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public byte Alpha {
            get {
                return this.alphaField;
            }
            set {
                this.alphaField = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
    public partial class RootClass {

        private SampleClass[] sampleClassesField;

        /// <remarks/>
        public SampleClass[] SampleClasses {
            get {
                return this.sampleClassesField;
            }
            set {
                this.sampleClassesField = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
    public partial class ArrayOfSampleClass {

        private SampleClass[] sampleClassField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("SampleClass", IsNullable=true)]
        public SampleClass[] SampleClass {
            get {
                return this.sampleClassField;
            }
            set {
                this.sampleClassField = value;
            }
        }
    }
}

注意:

  • 没有名称以 Specified 结尾的属性.

  • 属性 Something , SomeEnumSomeDateTime已变为可为空。

  • 已经可以为 null 的 public decimal? SomeNullable { get; set; }往返public System.Nullable<decimal> SomeNullable而不是通过成为一些可怕的双空 System.Nullable<System.Nullable<decimal>> 而失败.

然后我根据初始 RootClass 生成了以下 XML :

<RootClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SampleClasses>
    <SampleClass Id="10101">
      <Something>2.718</Something>
      <SomeEnum>ThirdValue</SomeEnum>
      <SomeString>hello</SomeString>
      <SomeNullable>3.14</SomeNullable>
      <SomeDateTime>2017-02-28T00:00:00-05:00</SomeDateTime>
      <MyColor Web="Maroon" />
    </SampleClass>
  </SampleClasses>
</RootClass>

并且能够成功地将其反序列化为生成的类 Question42295155.RootClass没有数据丢失。

注意 - 此代码经过轻微测试。如果您想提供一个示例模式,我可以重新测试。

有关详细信息,请参阅 Code Generation in the .NET Framework Using XML Schema .

关于c# - XmlCodeExporter 和可为 null 的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42295155/

有关c# - XmlCodeExporter 和可为 null 的类型的更多相关文章

  1. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  2. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  3. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  4. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  5. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  6. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  7. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  8. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  9. "\0"null 的 Ruby 测试? - 2

    我在破坏脚本的字符串中出现了一些奇怪的字符。据我所知,通过putbadstring到控制台,它们是"\0\0\0\0"。我想对此进行测试,以便我可以忽略它们...但是如何呢?以为这就是blank?和empty?的用途?!?:>badstring="\0"=>"\u0000">badstring.blank?NoMethodError:undefinedmethod`blank?'for"\u0000":Stringfrom(irb):97from/Users/meltemi/.rvm/rubies/ruby-2.0.0-p195/bin/irb:16:in`'>badstring.em

  10. ruby-on-rails - Rails 迁移中的 PostgreSQL 点类型 - 2

    我想使用PostgreSQL中的point类型。我已经完成了:railsgmodelTestpoint:point最终的迁移是:classCreateTests当我运行时:rakedb:migrate结果是:==CreateTests:migrating====================================================--create_table(:tests)rakeaborted!Anerrorhasoccurred,thisandalllatermigrationscanceled:undefinedmethod`point'for#/hom

随机推荐