CodeTypeParameter 类

定义

表示泛型类型或方法的类型参数。Represents a type parameter of a generic type or method.

public ref class CodeTypeParameter : System::CodeDom::CodeObject
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
[System.Serializable]
public class CodeTypeParameter : System.CodeDom.CodeObject
type CodeTypeParameter = class
    inherit CodeObject
Public Class CodeTypeParameter
Inherits CodeObject
继承
CodeTypeParameter
属性

示例

下面的代码示例演示如何使用CodeTypeParameter类创建一个 CodeDOM 图, 以生成包含泛型代码的应用程序。The following code example shows the use of the CodeTypeParameter class to create a CodeDOM graph to generate an application containing generics code.

using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Collections.Generic;
namespace System.CodeDom
{
    class CodeDomGenericsDemo
    {
        static void Main()
        {
            try
            {
                CreateGenericsCode("cs", "Generic.cs", "GenericCS.exe");
            }
            catch (Exception e)
            {
                LogMessage("Unexpected Exception:" + e.ToString());
            }
        }

        static void CreateGenericsCode(string providerName, string sourceFileName, string assemblyName)
        {

            CodeDomProvider provider = CodeDomProvider.CreateProvider(providerName);

            LogMessage("Building CodeDOM graph...");

            CodeCompileUnit cu = new CodeCompileUnit();

            CreateGraph(provider, cu);

            StringWriter sw = new StringWriter();

            LogMessage("Generating code...");
            provider.GenerateCodeFromCompileUnit(cu, sw, null);

            string output = sw.ToString();
            output = Regex.Replace(output, "Runtime Version:[^\r\n]*",
                "Runtime Version omitted for demo");

            LogMessage("Dumping source...");
            LogMessage(output);

            LogMessage("Writing source to file...");
            Stream s = File.Open(sourceFileName, FileMode.Create);
            StreamWriter t = new StreamWriter(s);
            t.Write(output);
            t.Close();
            s.Close();

            CompilerParameters opt = new CompilerParameters(new string[]{
                                      "System.dll", 
                                      "System.Xml.dll",
                                      "System.Windows.Forms.dll",
                                      "System.Data.dll",
                                      "System.Drawing.dll"});
            opt.GenerateExecutable = false;
            opt.TreatWarningsAsErrors = true;
            opt.IncludeDebugInformation = true;
            opt.GenerateInMemory = true;

            CompilerResults results;

            LogMessage("Compiling with " + providerName);
            results = provider.CompileAssemblyFromFile(opt, sourceFileName);

            OutputResults(results);
            if (results.NativeCompilerReturnValue != 0)
            {
                LogMessage("");
                LogMessage("Compilation failed.");
            }
            else
            {
                LogMessage("");
                LogMessage("Demo completed successfully.");
            }
            File.Delete(sourceFileName);
        }

        // Create a CodeDOM graph.
        static void CreateGraph(CodeDomProvider provider, CodeCompileUnit cu)
        {
            if (!provider.Supports(GeneratorSupport.GenericTypeReference |
               GeneratorSupport.GenericTypeDeclaration))
            {
                // Return if the generator does not support generics.
                return;
            }

            CodeNamespace ns = new CodeNamespace("DemoNamespace");
            ns.Imports.Add(new CodeNamespaceImport("System"));
            ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
            cu.Namespaces.Add(ns);

            // Declare a generic class.
            CodeTypeDeclaration class1 = new CodeTypeDeclaration();
            class1.Name = "MyDictionary";
            class1.BaseTypes.Add(new CodeTypeReference("Dictionary",
                                      new CodeTypeReference[] {
                                          new CodeTypeReference("TKey"),    
                                          new CodeTypeReference("TValue"),    
                                     }));
            CodeTypeParameter kType = new CodeTypeParameter("TKey");
            kType.HasConstructorConstraint = true;
            kType.Constraints.Add(new CodeTypeReference(typeof(IComparable)));
            kType.CustomAttributes.Add(new CodeAttributeDeclaration(
                "System.ComponentModel.DescriptionAttribute",
                    new CodeAttributeArgument(new CodePrimitiveExpression("KeyType"))));

            CodeTypeReference iComparableT = new CodeTypeReference("IComparable");
            iComparableT.TypeArguments.Add(new CodeTypeReference(kType));

            kType.Constraints.Add(iComparableT);

            CodeTypeParameter vType = new CodeTypeParameter("TValue");
            vType.Constraints.Add(new CodeTypeReference(typeof(IList<System.String>)));
            vType.CustomAttributes.Add(new CodeAttributeDeclaration(
                "System.ComponentModel.DescriptionAttribute",
                    new CodeAttributeArgument(new CodePrimitiveExpression("ValueType"))));

            class1.TypeParameters.Add(kType);
            class1.TypeParameters.Add(vType);

            ns.Types.Add(class1);

            // Declare a generic method.
            CodeMemberMethod printMethod = new CodeMemberMethod();
            CodeTypeParameter sType = new CodeTypeParameter("S");
            sType.HasConstructorConstraint = true;
            CodeTypeParameter tType = new CodeTypeParameter("T");
            sType.HasConstructorConstraint = true;

            printMethod.Name = "Print";
            printMethod.TypeParameters.Add(sType);
            printMethod.TypeParameters.Add(tType);

            printMethod.Statements.Add(ConsoleWriteLineStatement(
                new CodeDefaultValueExpression(new CodeTypeReference("T"))));
            printMethod.Statements.Add(ConsoleWriteLineStatement(
                new CodeDefaultValueExpression(new CodeTypeReference("S"))));

            printMethod.Attributes = MemberAttributes.Public;
            class1.Members.Add(printMethod);

            CodeTypeDeclaration class2 = new CodeTypeDeclaration();
            class2.Name = "Demo";

            CodeEntryPointMethod methodMain = new CodeEntryPointMethod();

            CodeTypeReference myClass = new CodeTypeReference(
                "MyDictionary",
                new CodeTypeReference[] {
                    new CodeTypeReference(typeof(int)),
                    new CodeTypeReference("List", 
                       new CodeTypeReference[] 
                            {new CodeTypeReference("System.String") })});

            methodMain.Statements.Add(
                  new CodeVariableDeclarationStatement(myClass,
                      "dict",
                          new CodeObjectCreateExpression(myClass)));

            methodMain.Statements.Add(ConsoleWriteLineStatement(
                new CodePropertyReferenceExpression(
                      new CodeVariableReferenceExpression("dict"),
                            "Count")));

            methodMain.Statements.Add(new CodeExpressionStatement(
                 new CodeMethodInvokeExpression(
                      new CodeMethodReferenceExpression(
                         new CodeVariableReferenceExpression("dict"),
                             "Print",
                                 new CodeTypeReference[] {
                                    new CodeTypeReference("System.Decimal"),
                                       new CodeTypeReference("System.Int32"),}),
                                           new CodeExpression[0])));

            string dictionaryTypeName = typeof(System.Collections.Generic.Dictionary<int,
                System.Collections.Generic.List<string>>[]).FullName;

            CodeTypeReference dictionaryType = new CodeTypeReference(dictionaryTypeName);
            methodMain.Statements.Add(
                  new CodeVariableDeclarationStatement(dictionaryType, "dict2",
                     new CodeArrayCreateExpression(dictionaryType, new CodeExpression[1] { new CodePrimitiveExpression(null) })));

            methodMain.Statements.Add(ConsoleWriteLineStatement(
                           new CodePropertyReferenceExpression(
                                new CodeVariableReferenceExpression("dict2"),
                                        "Length")));

            class2.Members.Add(methodMain);
            ns.Types.Add(class2);

        }

        static CodeStatement ConsoleWriteLineStatement(CodeExpression exp)
        {
            return new CodeExpressionStatement(
                new CodeMethodInvokeExpression(
                   new CodeMethodReferenceExpression(
                       new CodeTypeReferenceExpression(new CodeTypeReference("Console")),
                           "WriteLine"),
                               new CodeExpression[]{
                                   exp,
                                     }));
        }

        static CodeStatement ConsoleWriteLineStatement(string text)
        {
            return ConsoleWriteLineStatement(new CodePrimitiveExpression(text));
        }
        static void LogMessage(string text)
        {
            Console.WriteLine(text);
        }

        static void OutputResults(CompilerResults results)
        {
            LogMessage("NativeCompilerReturnValue=" +
                results.NativeCompilerReturnValue.ToString());
            foreach (string s in results.Output)
            {
                LogMessage(s);
            }
        }

    }
}
// This example generates the following code:
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version omitted for demo
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

//namespace DemoNamespace
//{
//    using System;
//    using System.Collections.Generic;


//    public class MyDictionary<[System.ComponentModel.DescriptionAttribute("KeyType")]  TKey,
//          [System.ComponentModel.DescriptionAttribute("ValueType")]  TValue> : Dictionary<TKey, TValue>
//        where TKey : System.IComparable, IComparable<TKey>, new()
//        where TValue : System.Collections.Generic.IList<string>
//    {

//        public virtual void Print<S, T>()
//            where S : new()
//        {
//            Console.WriteLine(default(T));
//            Console.WriteLine(default(S));
//        }
//    }

//    public class Demo
//    {

//        public static void Main()
//        {
//            MyDictionary<int, List<string>> dict = new MyDictionary<int, List<string>>();
//            Console.WriteLine(dict.Count);
//            dict.Print<decimal, int>();
//            System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<string>>[] dict2 =
//              new System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<string>>[] { null };
//            Console.WriteLine(dict2.Length);
//        }
//    }
//}

Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.Collections
Imports System.Collections.Specialized
Imports System.IO
Imports System.Reflection
Imports System.Text.RegularExpressions
Imports System.Globalization
Imports System.Collections.Generic


Class CodeDomGenericsDemo

    Shared Sub Main()
        Try
            CreateGenericsCode("vb", "Generic.vb", "GenericVB.exe")
        Catch e As Exception
            LogMessage(("Unexpected Exception:" + e.ToString()))
        End Try

    End Sub


    Shared Sub CreateGenericsCode(ByVal providerName As String, ByVal sourceFileName As String, ByVal assemblyName As String)

        Dim provider As CodeDomProvider = CodeDomProvider.CreateProvider(providerName)

        LogMessage("Building CodeDOM graph...")

        Dim cu As New CodeCompileUnit()

        CreateGraph(provider, cu)

        Dim sw As New StringWriter()

        LogMessage("Generating code...")
        provider.GenerateCodeFromCompileUnit(cu, sw, Nothing)

        Dim output As String = sw.ToString()
        output = Regex.Replace(output, "Runtime version:[^" + vbCr + vbLf + "]*", "Runtime version omitted for demo")

        LogMessage("Displaying source code...")
        LogMessage(output)

        LogMessage("Writing source code to file...")
        Dim s As Stream = File.Open(sourceFileName, FileMode.Create)
        Dim t As New StreamWriter(s)
        t.Write(output)
        t.Close()
        s.Close()

        Dim opt As New CompilerParameters(New String() {"System.dll", "System.Xml.dll", "System.Windows.Forms.dll", "System.Data.dll", "System.Drawing.dll"})
        opt.GenerateExecutable = False
        opt.TreatWarningsAsErrors = True
        opt.IncludeDebugInformation = True
        opt.GenerateInMemory = True

        Dim results As CompilerResults

        LogMessage(("Compiling with provider " + providerName))
        results = provider.CompileAssemblyFromFile(opt, sourceFileName)

        OutputResults(results)
        If results.NativeCompilerReturnValue <> 0 Then
            LogMessage("")
            LogMessage("Compilation failed.")
        Else
            LogMessage("")
            LogMessage("Demo completed successfully.")
        End If
        File.Delete(sourceFileName)

    End Sub


    ' Create a CodeDOM graph.
    Shared Sub CreateGraph(ByVal provider As CodeDomProvider, ByVal cu As CodeCompileUnit)
        ' Determine if the generator supports generics.
        If Not provider.Supports(GeneratorSupport.GenericTypeReference Or GeneratorSupport.GenericTypeDeclaration) Then
            ' Return if the generator does not support generics.
            Return
        End If
        Dim ns As New CodeNamespace("DemoNamespace")
        ns.Imports.Add(New CodeNamespaceImport("System"))
        ns.Imports.Add(New CodeNamespaceImport("System.Collections.Generic"))
        cu.Namespaces.Add(ns)

        ' Declare a generic class.
        Dim class1 As New CodeTypeDeclaration()
        class1.Name = "MyDictionary"
        class1.BaseTypes.Add( _
            New CodeTypeReference("Dictionary", _
                New CodeTypeReference() {New CodeTypeReference("TKey"), _
                    New CodeTypeReference("TValue")}))
        Dim kType As New CodeTypeParameter("TKey")
        kType.HasConstructorConstraint = True
        kType.Constraints.Add(New CodeTypeReference(GetType(IComparable)))
        kType.CustomAttributes.Add _
            (New CodeAttributeDeclaration("System.ComponentModel.DescriptionAttribute", _
                New CodeAttributeArgument(New CodePrimitiveExpression("KeyType"))))
        Dim iComparableT As New CodeTypeReference("IComparable")
        iComparableT.TypeArguments.Add(New CodeTypeReference(kType))

        kType.Constraints.Add(iComparableT)

        Dim vType As New CodeTypeParameter("TValue")
        vType.Constraints.Add(New CodeTypeReference(GetType(IList(Of System.String))))
        vType.CustomAttributes.Add _
            (New CodeAttributeDeclaration("System.ComponentModel.DescriptionAttribute", _
                New CodeAttributeArgument(New CodePrimitiveExpression("ValueType"))))

        class1.TypeParameters.Add(kType)
        class1.TypeParameters.Add(vType)
        ns.Types.Add(class1)

        ' Declare a generic method.
        Dim printMethod As New CodeMemberMethod()
        Dim sType As New CodeTypeParameter("S")
        sType.HasConstructorConstraint = True
        Dim tType As New CodeTypeParameter("T")
        tType.HasConstructorConstraint = True

        printMethod.Name = "Print"
        printMethod.TypeParameters.Add(sType)
        printMethod.TypeParameters.Add(tType)

        printMethod.Statements.Add(ConsoleWriteLineStatement _
            (New CodeDefaultValueExpression(New CodeTypeReference("T"))))
        printMethod.Statements.Add(ConsoleWriteLineStatement _
            (New CodeDefaultValueExpression(New CodeTypeReference("S"))))
        printMethod.Attributes = MemberAttributes.Public
        class1.Members.Add(printMethod)

        Dim class2 As New CodeTypeDeclaration()
        class2.Name = "Demo"

        Dim methodMain As New CodeEntryPointMethod()

        Dim [myClass] As New CodeTypeReference("MyDictionary", _
            New CodeTypeReference() {New CodeTypeReference(GetType(Integer)), _
                New CodeTypeReference("List", _
                    New CodeTypeReference() {New CodeTypeReference("System.String")})})

        methodMain.Statements.Add(New CodeVariableDeclarationStatement([myClass], _
            "dict", New CodeObjectCreateExpression([myClass])))

        methodMain.Statements.Add(ConsoleWriteLineStatement _
            (New CodePropertyReferenceExpression _
                (New CodeVariableReferenceExpression("dict"), "Count")))

        methodMain.Statements.Add _
            (New CodeExpressionStatement _
                (New CodeMethodInvokeExpression _
                    (New CodeMethodReferenceExpression _
                        (New CodeVariableReferenceExpression("dict"), _
                            "Print", New CodeTypeReference() _
                                    {New CodeTypeReference("System.Decimal"), _
                                        New CodeTypeReference("System.Int32")}), _
                                            New CodeExpression(-1) {})))
        Dim longTypeName As String = GetType( _
            System.Collections.Generic.Dictionary(Of Integer, _
                System.Collections.Generic.List(Of String))()).FullName

        Dim longType As New CodeTypeReference(longTypeName)

        methodMain.Statements.Add(New CodeVariableDeclarationStatement _
            (longType, "dict2", New CodeArrayCreateExpression _
                (longType, New CodeExpression(0) {New CodePrimitiveExpression(Nothing)})))

        methodMain.Statements.Add(ConsoleWriteLineStatement(New CodePropertyReferenceExpression(New CodeVariableReferenceExpression("dict2"), "Length")))

        class2.Members.Add(methodMain)
        ns.Types.Add(class2)

    End Sub


    Overloads Shared Function ConsoleWriteLineStatement(ByVal exp As CodeExpression) As CodeStatement
        Return New CodeExpressionStatement(New CodeMethodInvokeExpression _
            (New CodeMethodReferenceExpression _
                (New CodeTypeReferenceExpression _
                    (New CodeTypeReference("Console")), "WriteLine"), _
                        New CodeExpression() {exp}))

    End Function 'ConsoleWriteLineStatement


    Overloads Shared Function ConsoleWriteLineStatement(ByVal [text] As String) As CodeStatement
        Return ConsoleWriteLineStatement(New CodePrimitiveExpression([text]))

    End Function 'ConsoleWriteLineStatement

    Shared Sub LogMessage(ByVal [text] As String)
        Console.WriteLine([text])

    End Sub


    Shared Sub OutputResults(ByVal results As CompilerResults)
        LogMessage(("NativeCompilerReturnValue=" + results.NativeCompilerReturnValue.ToString()))
        Dim s As String
        For Each s In results.Output
            LogMessage(s)
        Next s

    End Sub
End Class
'
' This example generates the following code:
'------------------------------------------------------------------------------
' <auto-generated>
'     This code was generated by a tool.
'     Runtime Version:2.0.50727.1434
'
'     Changes to this file may cause incorrect behavior and will be lost if
'     the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------

'Option Strict Off
'Option Explicit On

''Imports System.Collections.Generic

'Namespace DemoNamespace

'    Public Class MyDictionary(Of TKey As  {System.IComparable, IComparable(Of TKey), New}, TValue As System.Collections.
'Generic.IList(Of String))
'        Inherits Dictionary(Of TKey, TValue)

'        Public Overridable Sub Print(Of S As New, T As New)()
'            Console.WriteLine(CType(Nothing, T))
'            Console.WriteLine(CType(Nothing, S))
'        End Sub
'    End Class

'    Public Class Demo

'        Public Shared Sub Main()
'            Dim dict As MyDictionary(Of Integer, List(Of String)) = New MyDictionary(Of Integer, List(Of String))
'            Console.WriteLine(dict.Count)
'            dict.Print(Of Decimal, Integer)()
'            Dim dict2() As System.Collections.Generic.Dictionary(Of Integer, System.Collections.Generic.List(Of String))
' = New System.Collections.Generic.Dictionary(Of Integer, System.Collections.Generic.List(Of String))() {Nothing}
'            Console.WriteLine(dict2.Length)
'        End Sub
'    End Class
'End Namespace

注解

CodeTypeParameter类表示泛型类型或方法的声明中的类型参数。The CodeTypeParameter class represents a type parameter in the declaration of a generic type or method.

泛型类型或方法声明包含一个或多个未指定的类型 (称为类型参数)。A generic type or method declaration contains one or more unspecified types known as type parameters. 类型参数名称代表泛型声明主体中的类型。A type parameter name stands for the type within the body of the generic declaration. 例如, List<T>类的泛型声明包含类型参数TFor example, the generic declaration for the List<T> class contains the type parameter T.

有关泛型的详细信息, 请参阅.NET Framework 类库中的泛型For more information on generics, see Generics in the .NET Framework Class Library.

构造函数

CodeTypeParameter()

初始化 CodeTypeParameter 类的新实例。Initializes a new instance of the CodeTypeParameter class.

CodeTypeParameter(String)

用指定的类型参数名称初始化 CodeTypeParameter 类的新实例。Initializes a new instance of the CodeTypeParameter class with the specified type parameter name.

属性

Constraints

获取类型参数的约束。Gets the constraints for the type parameter.

CustomAttributes

获取类型参数的自定义特性。Gets the custom attributes of the type parameter.

HasConstructorConstraint

获取或设置一个值,该值指示类型参数是否具有构造函数约束。Gets or sets a value indicating whether the type parameter has a constructor constraint.

Name

获取或设置类型参数的名称。Gets or sets the name of the type parameter.

UserData

获取当前对象的用户可定义数据。Gets the user-definable data for the current object.

(继承自 CodeObject)

方法

Equals(Object)

确定指定的对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(继承自 Object)
GetHashCode()

作为默认哈希函数。Serves as the default hash function.

(继承自 Object)
GetType()

获取当前实例的 TypeGets the Type of the current instance.

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(继承自 Object)
ToString()

返回表示当前对象的字符串。Returns a string that represents the current object.

(继承自 Object)

适用于