你如何给一个C#自动属性使用自定义属性的默认值? [英] How do you give a C# Auto-Property a default value using a custom attribute?

查看:2920
本文介绍了你如何给一个C#自动属性使用自定义属性的默认值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你如何给一个C#自动属性的默认值,使用自定义属性?

How do you give a C# Auto-Property a default value, using a custom attribute?

这是在code我想看看:

This is the code I want to see:

class Person 
{
    [MyDefault("William")]
    public string Name { get; set; }
}

据我所知,没有内置的方法使用属性初始化默认 - ?我可以写我自己的自定义类使用我的自定义属性初始化默认

I am aware that there is no built in method to initialize the default using an attribute - can I write my own custom class that uses my custom attributes to initialize the default?

推荐答案

您可以使用一个辅助类这样的:

You could use a helper class like that:

public class DefaultValueHelper
{
    public static void InitializeDefaultValues<T>(T obj)
    {
        var properties =
            (from prop in obj.GetType().GetProperties()
             let attr = GetDefaultValueAttribute(prop)
             where attr != null
             select new
             {
                Property = prop,
                DefaultValue = attr.Value
             }).ToArray();
        foreach (var p in properties)
        {
            p.Property.SetValue(obj, p.DefaultValue, null);
        }

    }

    private static DefaultValueAttribute GetDefaultValueAttribute(PropertyInfo prop)
    {
        return prop.GetCustomAttributes(typeof(DefaultValueAttribute), true)
                   .Cast<DefaultValueAttribute>()
                   .FirstOrDefault();
    }
}

和呼叫 InitializeDefaultValues​​ 在类的构造函数。

And call InitializeDefaultValues in the constructor of your class.

class Foo
{
    public Foo()
    {
        DefaultValueHelper.InitializeDefaultValues(this);
    }

    [DefaultValue("(no name)")]
    public string Name { get; set; }
}


编辑:更新版本,生成并缓存的委托做初始化。这是为了避免使用反射每次方法被称为对于给定的类型的时间


updated version, which generates and caches a delegate to do the initialization. This is to avoid using reflection every time the method is called for a given type.

public static class DefaultValueHelper
{
    private static readonly Dictionary<Type, Action<object>> _initializerCache;

    static DefaultValueHelper()
    {
        _initializerCache = new Dictionary<Type, Action<object>>();
    }

    public static void InitializeDefaultValues(object obj)
    {
        if (obj == null)
            return;

        var type = obj.GetType();
        Action<object> initializer;
        if (!_initializerCache.TryGetValue(type, out initializer))
        {
            initializer = MakeInitializer(type);
            _initializerCache[type] = initializer;
        }
        initializer(obj);
    }

    private static Action<object> MakeInitializer(Type type)
    {
        var arg = Expression.Parameter(typeof(object), "arg");
        var variable = Expression.Variable(type, "x");
        var cast = Expression.Assign(variable, Expression.Convert(arg, type));
        var assignments =
            from prop in type.GetProperties()
            let attr = GetDefaultValueAttribute(prop)
            where attr != null
            select Expression.Assign(Expression.Property(variable, prop), Expression.Constant(attr.Value));

        var body = Expression.Block(
            new ParameterExpression[] { variable },
            new Expression[] { cast }.Concat(assignments));
        var expr = Expression.Lambda<Action<object>>(body, arg);
        return expr.Compile();
    }

    private static DefaultValueAttribute GetDefaultValueAttribute(PropertyInfo prop)
    {
        return prop.GetCustomAttributes(typeof(DefaultValueAttribute), true)
                   .Cast<DefaultValueAttribute>()
                   .FirstOrDefault();
    }
}

这篇关于你如何给一个C#自动属性使用自定义属性的默认值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆