0

CodeDom を使用してこのようなものを構築する方法を見つけようとしています

public System.Collections.Generic.Dictionary<string, string> Attributes
{
    get
    {
        return new System.Collections.Generic.Dictionary<string, string>()
        {
            {"firstkey", "first value"},
            {"second", "second value"},
            {"third", "third value"}
        };
    }
}

私はこれを読みましたが、私が望むところには行きませんでしたhttp://msdn.microsoft.com/en-us/library/system.codedom.codetypeparameter.aspx

これは私がしました

Type myType = typeof (System.Collections.Generic.Dictionary<string, string>);
string dictionaryTypeName = myType.FullName;

CodeTypeReference dictionaryType = new CodeTypeReference(dictionaryTypeName);

var abc = new CodeVariableDeclarationStatement(
    dictionaryType, "dict2",
    new CodeObjectCreateExpression(
        dictionaryType, new CodeSnippetExpression(@"{""firstkey"", ""first value""}")
        )
    );

property.GetStatements.Add(abc);

これを生成します

public Dictionary<object, object> Attributes
{
    get
    {
        Dictionary<string, string> dict2 = new Dictionary<string, string>({"firstkey", "first value"});
    }
}

似たようなものを作った人はいますか?

4

2 に答える 2

1

コンストラクターにパラメーターとして値を追加する代わりに、.addを使用する必要がありました。

if (type == typeof(Dictionary<string, string>))
{
    string variableName = "dict";

    CodeVariableDeclarationStatement codeVariableDeclarationStatement = new CodeVariableDeclarationStatement(new CodeTypeReference(type.FullName), variableName,
            new CodeObjectCreateExpression(type)
    );

    property.GetStatements.Add(codeVariableDeclarationStatement);
    property.GetStatements.Add(AddPropertyValues(new CodeSnippetExpression(string.Format(@"""{0}"", ""{1}""", "a", "xx xx1")), variableName));
    property.GetStatements.Add(AddPropertyValues(new CodeSnippetExpression(string.Format(@"""{0}"", ""{1}""", "b", "xx xx2")), variableName));
    property.GetStatements.Add(AddPropertyValues(new CodeSnippetExpression(string.Format(@"""{0}"", ""{1}""", "c", "xx xx3")), variableName));

    property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(variableName)));
}

static CodeStatement AddPropertyValues(CodeExpression exp, string variableReference)
{
    return new CodeExpressionStatement(
        new CodeMethodInvokeExpression(
            new CodeMethodReferenceExpression(
                new CodeTypeReferenceExpression(new CodeTypeReference(variableReference)),
                    "Add"),
                        new CodeExpression[]{
                            exp,
                                }));
}

これを生成します

public System.Collections.Generic.Dictionary<string, string> Attributes
{
    get
    {
        System.Collections.Generic.Dictionary<string, string> dict = new System.Collections.Generic.Dictionary<string, string>();
        dict.Add("a", "xx xx1");
        dict.Add("b", "xx xx2");
        dict.Add("c", "xx xx3");
        return dict;
    }
}

けっこうだ!

于 2012-09-19T09:47:12.307 に答える
1

Add メソッドを使用する代わりに初期化を使用する場合は、コンストラクターの呼び出しにも Snippet の方法を使用する必要があります。型名を定数文字列に書きたくない場合、これはより困難になる可能性があります。この場合、パラメーターなしのコンストラクターへの呼び出しを作成し、CSharpCodeProvider を使用してコンストラクターの呼び出しを表す文字列を取得し、最後の括弧を破棄して、初期化スニペットを連結できます。コードは次のようになり、必要なコードが生成されます。

        CSharpCodeProvider codeProvider = new CSharpCodeProvider();
        CodeGeneratorOptions options = new CodeGeneratorOptions();
        options.IndentString = "   ";
        options.BracingStyle = "C";

        Type myType = typeof(System.Collections.Generic.Dictionary<string, string>);
        string dictionaryTypeName = myType.FullName;

        CodeTypeReference dictionaryType = new CodeTypeReference(dictionaryTypeName);

        // here you create the CodeobjectCreateExpression in order to obtain the string with the name of the type
        StringWriter sw = new StringWriter();
        CodeObjectCreateExpression createExpr = new CodeObjectCreateExpression(dictionaryType);
        codeProvider.GenerateCodeFromExpression(createExpr, sw, options);
        string creationCode = sw.ToString();
        // throw away the final ()
        creationCode = creationCode.Substring(0, creationCode.Length - 2);
        // add initialization
        creationCode = creationCode + @"{{""firstkey"", ""first value""}, {""secondkey"", ""second value""}, {""thirdkey"", ""third value""}}";
        CodeMethodReturnStatement retVal = new CodeMethodReturnStatement(new CodeSnippetExpression(creationCode));
        property.GetStatements.Add(retVal);
于 2012-09-19T12:43:05.743 に答える