Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从属性中获取类型以执行方法?_C#_.net - Fatal编程技术网

C# 如何从属性中获取类型以执行方法?

C# 如何从属性中获取类型以执行方法?,c#,.net,C#,.net,我想知道你可以通过反射得到一个类型来执行一个实现特定接口的方法 系统属性实现 [AttributeUsage( AttributeTargets.Property )] public class ExampleAttribute : Attribute { public ExampleAttribute( string key ) { Key = key; } public stri

我想知道你可以通过反射得到一个类型来执行一个实现特定接口的方法

系统属性实现

    [AttributeUsage( AttributeTargets.Property )]
    public class ExampleAttribute : Attribute
    {
        public ExampleAttribute( string key )
        {
            Key = key;
        }

        public string Key { get; set; }

        public Type Executor { get; set; }
    }
使用属性批注AttributeTargets.Property的模型

    public class Example
    {
        [ExampleAttribute( "property" )]
        public string Property { get; set; }

        [ExampleAttribute( "lock", Executor = typeof( LockExecutor ) )]
        public string Lock { get; set; }
    }

我想知道如何通过反射IExecutor类型的对象来执行特定的实现锁执行器

我不确定需求背后的原因是什么,但您可以使用以下代码:

var example = new Example() { Property = "x", Lock = "y" };
var property = example.GetType().GetProperty("Lock");
var attribute = property.GetCustomAttributes(true).OfType<ExampleAttribute>().FirstOrDefault();
var executer = Activator.CreateInstance(attribute.Executor);
var method = attribute.Executor.GetMethod("TranslateValue");
var result = method.Invoke(executer, new[] { example.Lock });

我不确定需求背后的理性是什么,但您可以使用以下代码:

var example = new Example() { Property = "x", Lock = "y" };
var property = example.GetType().GetProperty("Lock");
var attribute = property.GetCustomAttributes(true).OfType<ExampleAttribute>().FirstOrDefault();
var executer = Activator.CreateInstance(attribute.Executor);
var method = attribute.Executor.GetMethod("TranslateValue");
var result = method.Invoke(executer, new[] { example.Lock });

我希望它不是在试图翻译一些东西,它只是一个抽象概念

var ex = new Example{Property = "Prop", Lock = "LOCK"};
        var type = ex.GetType();
        var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public) // get properties
            .Select(t =>
        {
            var attr = t.GetCustomAttribute<ExampleAttribute>(); // read attribute
            var executor = attr == null ? null :attr.Executor; // it has attribute?
            IExecutor instance = null;
            if (executor != null) // attribute has executor
                instance = (IExecutor)Activator.CreateInstance(executor); // create instance
            return new
            {
            Property = t, Executor = instance
            };
        }

        ).Where(t => t.Executor != null).ToList(); // select the ones which has executor
        properties.ForEach(t =>
        {
            var val = t.Property.GetValue(ex); // get value from instance
            var translated = t.Executor.TranslateValue(val); // execute
            Console.WriteLine(translated); // dump
        }

        );

我希望它不是在试图翻译一些东西,它只是一个抽象概念

var ex = new Example{Property = "Prop", Lock = "LOCK"};
        var type = ex.GetType();
        var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public) // get properties
            .Select(t =>
        {
            var attr = t.GetCustomAttribute<ExampleAttribute>(); // read attribute
            var executor = attr == null ? null :attr.Executor; // it has attribute?
            IExecutor instance = null;
            if (executor != null) // attribute has executor
                instance = (IExecutor)Activator.CreateInstance(executor); // create instance
            return new
            {
            Property = t, Executor = instance
            };
        }

        ).Where(t => t.Executor != null).ToList(); // select the ones which has executor
        properties.ForEach(t =>
        {
            var val = t.Property.GetValue(ex); // get value from instance
            var translated = t.Executor.TranslateValue(val); // execute
            Console.WriteLine(translated); // dump
        }

        );

我认为你的代码有代码的味道,请描述你试图解决的问题,我很确定不需要属性就可以解决问题这是对需求的抽象和简化。我理解您的意思,因为您只看到代码的一小部分,但我认为问题需要这种解决方案。谢谢你的评论和时间。@juan如果来自Eldar的解决方案对你有效,请将其标记为答案。没有必要把它或任何修改这回到你原来的职位。我认为你的代码有代码的味道,请描述你试图解决的问题,我很确定不需要属性就可以解决问题这是对需求的抽象和简化。我理解您的意思,因为您只看到代码的一小部分,但我认为问题需要这种解决方案。谢谢你的评论和时间。@juan如果来自Eldar的解决方案对你有效,请将其标记为答案。没有必要把它或任何修改这回到你原来的职位。这可能会给未来的读者带来困惑。将CreateInstance返回的对象强制转换为IExecutor并直接调用它会比使用反射执行TranslateValue更简单。@StriplingWarrior是的,你完全正确。但我想展示Juan如何使用反射来获得一个方法并调用它。@devquestions谢谢您的回答。您的解决方案也是正确的,而且更详细,也许它可以帮助其他人解决同样的问题。将CreateInstance返回的对象强制转换为IExecutor并直接调用它会更简单,而不是使用反射来执行TranslateValue。@StriplingWarrior是的,您完全正确。但我想展示Juan如何使用反射来获得一个方法并调用它。@devquestions谢谢您的回答。你的解决方案也是正确的,而且更详细,也许它可以帮助其他人解决同样的问题。是的,这只是问题@Eldar的一个抽象。我唯一遗漏的部分是instance=IExecutorActivator.CreateInstanceexecutor;。谢谢。是的,这只是问题的抽象@Eldar。我唯一遗漏的部分是instance=IExecutorActivator.CreateInstanceexecutor;。非常感谢。