public void GenericTypesAndConstraints()
{
CodeNamespace ns = new CodeNamespace("NS");
ns.Imports.Add(new CodeNamespaceImport("System"));
ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
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 = "Nop";
printMethod.TypeParameters.Add(sType);
printMethod.TypeParameters.Add(tType);
printMethod.Attributes = MemberAttributes.Public;
class1.Members.Add(printMethod);
var class2 = new CodeTypeDeclaration();
class2.Name = "Demo";
var methodMain = new CodeEntryPointMethod();
var 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)));
string dictionaryTypeName = typeof(System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<string>>[]).FullName;
var dictionaryType = new CodeTypeReference(dictionaryTypeName);
methodMain.Statements.Add(
new CodeVariableDeclarationStatement(dictionaryType, "dict2",
new CodeArrayCreateExpression(dictionaryType, new CodeExpression[1] { new CodePrimitiveExpression(null) })));
class2.Members.Add(methodMain);
ns.Types.Add(class2);
AssertEqual(ns,
@"namespace NS {
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 Nop<S, T>() where S : new() { }
}
public class Demo
{
public static void Main()
{
MyDictionary<int, List<string>> dict = new MyDictionary<int, List<string>>();
System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<string>>[] dict2 = new System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<string>>[] { null};
}
}
}");
}
}