C# create object instance with expression.new

金利 张 20 Reputation points
2024-10-05T07:22:53.52+00:00

I want to using expression to create object instance, at last i got an error. code bellow ` [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public class FieldAttribute : Attribute { private bool _isSizeExtracted; private string _size;

    public FieldAttribute(string dataType = null)
    {
        if (!string.IsNullOrWhiteSpace(dataType))
        {
            DataType = dataType.ToLower();
        }
    }

    public int? Index { get; set; }


    public string FieldName { get; set; }

    public bool HasDefaultValue { get; set; }


    public string DataType { get; set; }


    internal string Size
    {
        get
        {
            if (string.IsNullOrWhiteSpace(DataType)) return null;

            if (!_isSizeExtracted)
            {
                _isSizeExtracted = true;

                var i = DataType.IndexOf('(');
                if (i > 0)
                {
                    var j = DataType.IndexOf(')', i);
                    if (j > 0)
                    {
                        //_size = DataType[(i + 1)..j];
                    }
                }
            }

            return _size;
        }
    }
}

internal class TableInfo
{

}

internal class FieldInfoBase
{

    internal int Index { get; set; }


    internal string FieldName { get; set; }


    internal bool HasDefaultValue { get; set; }


    internal string FieldDataType { get; set; }

    internal Type PropertyType { get; set; }


    internal string Size { get; set; }


    internal bool FieldNameSameAsPropertyName { get; set; }

    internal virtual object GetValue(object objInstance) { return null; }
}

internal class FieldInfo<TUserData, TValue> : FieldInfoBase where TUserData : class
{
    private ConcurrentDictionary<Type, long[]> _hashes = null;

    protected bool _isValueType;

    protected Type _realPropertyType;

    public FieldInfo(TableInfo tableInfo, PropertyInfo propertyInfo, FieldAttribute attr, ref int columnIndex)
    {
        _hashes = new ConcurrentDictionary<Type, long[]>();

        HasDefaultValue = attr.HasDefaultValue;
        Size = attr.Size;
        FieldDataType = attr.DataType; 
        Index = attr.Index ?? columnIndex++;

        PropertyName = propertyInfo.Name;
        PropertyType = propertyInfo.PropertyType;

        FieldName = string.IsNullOrWhiteSpace(attr.FieldName) ? PropertyName : attr.FieldName;

        FieldNameSameAsPropertyName = PropertyName.Equals(attr.FieldName);


        if (!IsNullable && !_isValueType)
        {
            IsNullable = true;
        }
    }

    internal string PropertyName { get; private set; }

    internal bool IsPrimaryKey { get; set; }

    internal bool IsNullable { get; set; }

    public void SetValue(TUserData ins, TValue value)
    {

    }
}

public class UserInfo
{
    [Field]
    public int Id { get; set; }

    public int ParentId { get; set; }

    public string Address { get; set; }
}


public static void TestExpressionCreate<TUserData, TValue>() where TUserData : class
{
    var t = typeof(FieldInfo<,>);
    var d = t.MakeGenericType(typeof(TUserData), typeof(TValue));

    var ctor = d.GetConstructor([typeof(TableInfo), typeof(PropertyInfo), typeof(FieldAttribute), typeof(int).MakeByRefType()]);

    var tiExp = Expression.Parameter(typeof(TableInfo));
    var piExp = Expression.Parameter(typeof(PropertyInfo));
    var attrExp = Expression.Parameter(typeof(FieldAttribute));
    var indexExp = Expression.Parameter(typeof(int).MakeByRefType());

    var body = Expression.New(ctor, [tiExp, piExp, attrExp, indexExp]);
    var lambda = Expression.Lambda<Func<FieldInfo<TUserData, TValue>>>(body, [tiExp, piExp, attrExp, indexExp]).CompileFast();


    var table = new TableInfo();
    var pi = typeof(UserInfo).GetProperty("Id");
    var fieldAttr = pi.GetCustomAttribute<FieldAttribute>();
    var columnIndex = 0;

    Stopwatch watch = Stopwatch.StartNew();

    for (int i = 0; i < max; i++)
    {
        var ins = lambda.DynamicInvoke([table, pi, fieldAttr, columnIndex]); <--- error here
    }

    watch.Stop();
    Console.WriteLine(watch.ElapsedTicks);
}


static void Main(string[] args)
{


    TestExpressionCreate<UserInfo, int>();
    TestActivatorCreate();

    Console.ReadLine();
}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,404 questions
0 comments No comments
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.