C# 在C中从动态生成POCO#

C# 在C中从动态生成POCO#,c#,dynamic,reflection,code-generation,poco,C#,Dynamic,Reflection,Code Generation,Poco,.NET4.5中是否内置了任何东西,可以从动态生成一个包含所有自动实现属性的字符串C#POCO 如果没有,在.NET中是否有内置的东西可以提供(类似于)列表,以便我们可以根据伪代码生成POCO: foreach (var kvp in list) { builder.AppendFormat("public {0} {1} {{ get; set; }}", kvp.Value, kvp.Key); } 最后,是否有任何著名的库可以帮助生成这种非常基本的代码?您可以使用compilea

.NET4.5中是否内置了任何东西,可以从
动态
生成一个包含所有自动实现属性的字符串C#POCO

如果没有,在.NET中是否有内置的东西可以提供(类似于)
列表
,以便我们可以根据伪代码生成POCO:

foreach (var kvp in list)
{
    builder.AppendFormat("public {0} {1} {{ get; set; }}", kvp.Value, kvp.Key);
}

最后,是否有任何著名的库可以帮助生成这种非常基本的代码?

您可以使用
compileasemblyfromsource
来编译字符串

var csc=new CSharpCodeProvider(new Dictionary(){{“compilervision”,“v4.0”});
var cp=新编译器参数()
{
GenerateExecutable=false,
GenerateInMemory=true
};
添加(“mscorlib.dll”);
添加(“System.dll”);
添加(“System.Core.dll”);
//该字符串可以包含任何有效的c#代码
//需要使用自己的属性创建有效的类。
var s=“公共类POCOClass{public int ID{get{return 1;}}}}”;
//“结果”通常包含非常详细的错误消息
var results=csc.compileasemblyfromsource(cp,s);
var type=results.CompiledAssembly.GetType(“POCOClass”);
var obj=(动态)Activator.CreateInstance(类型);
var输出=对象ID;
//或
var output=obj.GetType().GetProperty(“ID”).GetValue(obj,null);
您需要为您的属性定义一个类,比如称为POCOClass的类

编辑:

public static T CopyObjectFromExpando<T>(this object s) where T : class
        {
            var source = (ExpandoObject)s;
            // Might as well take care of null references early.
            if (source == null)
            {
                throw new ArgumentNullException("s");
            }

            var propertyMap = typeof(T).GetProperties().ToDictionary(p => p.Name.ToLowerInvariant(), p => p);
            var destination = Activator.CreateInstance<T>();
            // By iterating the KeyValuePair<string, object> of
            // source we can avoid manually searching the keys of
            // source as we see in your original code.
            foreach (var kv in source)
            {
                PropertyInfo p;
                if (propertyMap.TryGetValue(kv.Key.ToLowerInvariant(), out p))
                {
                    var propType = p.PropertyType;
                    if (kv.Value == null)
                    {
                        if (!propType.IsNullable() && propType != typeof(string))
                        {
                            // Throw if type is a value type 
                            // but not Nullable<>
                            throw new ArgumentException("not nullable");
                        }
                    }
                    else if (propType.IsEnum)
                    {
                        var enumvalue = Enum.ToObject(propType, kv.Value);
                        p.SetValue(destination, enumvalue, null);
                        continue;
                    }
                    else if (propType == typeof(bool) && kv.Value.GetType() != typeof(bool))
                    {
                        var boolvalue = Convert.ToBoolean(kv.Value);
                        p.SetValue(destination, boolvalue, null);
                        continue;
                    }
                    else if (propType.IsNullable())
                    {
                        var nullType = Nullable.GetUnderlyingType(propType);
                        var value = Convert.ChangeType(kv.Value, nullType);
                        p.SetValue(destination, value, null);
                        continue;
                    }
                    else if (kv.Value.GetType() != propType)
                    {
                        // You could make this a bit less strict 
                        // but I don't recommend it.
                        throw new ArgumentException("type mismatch");
                    }
                    p.SetValue(destination, kv.Value, null);
                }
            }

            return destination;
        }
公共静态T CopyObjectFromExpando(此对象),其中T:class
{
变量源=(ExpandoObject)s;
//最好尽早处理空引用。
if(source==null)
{
抛出新的ArgumentNullException(“s”);
}
var propertyMap=typeof(T).GetProperties().ToDictionary(p=>p.Name.ToLowerInvariant(),p=>p);
var destination=Activator.CreateInstance();
//通过迭代
//source我们可以避免手动搜索
//我们在原始代码中看到的源代码。
foreach(电源中的var kv)
{
房地产信息;
if(propertyMap.TryGetValue(kv.Key.ToLowerInvariant(),out p))
{
var propType=p.PropertyType;
如果(千伏值==零)
{
如果(!propType.IsNullable()&&propType!=typeof(string))
{
//如果类型是值类型,则抛出
//但不能为空
抛出新ArgumentException(“不可为null”);
}
}
else if(propType.IsEnum)
{
var enumvalue=枚举对象(propType,千伏值);
p、 SetValue(目标,枚举值,null);
继续;
}
else if(propType==typeof(bool)和&kv.Value.GetType()!=typeof(bool))
{
var布尔值=转换为布尔值(千伏值);
p、 SetValue(目标,布尔值,null);
继续;
}
else if(propType.IsNullable())
{
var nullType=Nullable.getUnderlinegType(propType);
var值=转换转换类型(千伏值,空值类型);
p、 SetValue(目的地,值,null);
继续;
}
else if(kv.Value.GetType()!=propType)
{
//你可以让它不那么严格
//但我不推荐。
抛出新ArgumentException(“类型不匹配”);
}
p、 设置值(目的地,千伏值,空);
}
}
返回目的地;
}
,Nuget上的开源

PM> Install-Package ImpromptuInterface

通过
使用ImpromptuInterface

Impromput.ActLikeProperties(dynObj, list.ToDictionary(k=>k.Key,v=>v.Value))
这会在
dynObj


其目的是能够将简单的动态对象(如expando)连接到使用反射的旧代码。但一般来说,更好的做法是使用ImpromptuInterface的主要功能,即使用静态声明的接口包装动态对象。

Upvote,因为这对我正在做的其他事情非常有用,但它没有回答问题。我一直在寻找一种对给定的<代码>动态进行反向工程的方法,但在实现了我自己的“答案”后,我意识到这个问题可能太模糊了。好吧,那么,您可以将动态对象转换为字符串构建,如果我理解正确,您可以使用此代码。换句话说,如果您有一个用于转换动态对象的类型,例如POCOClass,并且如果您不想在不使用字符串的情况下转换动态对象,那么我有一个可以将动态对象转换为类型的助手,如果您愿意,我可以与您共享。当然,我很乐意看到它
Impromput.ActLikeProperties(dynObj, list.ToDictionary(k=>k.Key,v=>v.Value))