I have some code like this (using LinqPad):
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
void Main()
{
var cd = ClassDeclaration($"TestExtensions")
.AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword));
var method =
MethodDeclaration(ParseTypeName($"T"), $"SetTest")
.AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword))
.AddTypeParameterListParameters(TypeParameter(Identifier("T")))
.AddParameterListParameters(
Parameter(Identifier("definition")).WithType(ParseTypeName("T")).AddModifiers(Token(SyntaxKind.ThisKeyword)),
Parameter(Identifier("value")).WithType(ParseTypeName("int"))
)
.AddConstraintClauses(TypeParameterConstraintClause("T").WithConstraints(GetSL()))
.WithBody(Block(ParseStatement($"definition.SetField(\"test\", value);"), ParseStatement("return definition;")));
cd = cd.AddMembers(method);
// namespace
var ns = SyntaxFactory
.NamespaceDeclaration(ParseName("MyNS"))
.AddMembers(cd);
var cu = SyntaxFactory.CompilationUnit();
var code = cu.AddMembers(ns)
.NormalizeWhitespace()
.ToFullString();
// hack because I can't make .WithConstraints work
// code = code.Replace("where T :", $"where T : {t.Name}");
code.Dump();
}
SeparatedSyntaxList<TypeParameterConstraintSyntax> GetSL()
{
var list = SeparatedList<TypeParameterConstraintSyntax>();
list.Add(TypeConstraint(ParseTypeName($"Test")));
return list;
}
Which produces what I want except for the type constraint e.g.
namespace MyNS
{
public static class TestExtensions
{
public static T SetTest<T>(this T definition, int value)
where T :
{
definition.SetField("test", value);
return definition;
}
}
}
GetSL().ToFullString() produces an empty result.
I need the type constraint to be: where T : Test
I can't find any examples for WithConstraints() so far.
You almost got the correct result. The main issue in your GetSL
method. Because SeparatedSyntaxList<TypeParameterConstraintSyntax>
is immutable you have to use return value of Add
method.
That variant works:
var parameterConstraintClauseSyntax = SyntaxFactory.TypeParameterConstraintClause(
SyntaxFactory.IdentifierName("T"),
new SeparatedSyntaxList<TypeParameterConstraintSyntax>()
.Add(SyntaxFactory.TypeConstraint(SyntaxFactory.ParseTypeName("Test"))));
methodSyntax = methodSyntax.AddConstraintClauses(parameterConstraintClauseSyntax);