首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反射op_implicit表

反射op_implicit表
EN

Stack Overflow用户
提问于 2014-03-04 15:41:30
回答 2查看 2.5K关注 0票数 1

我现在想要建立动态类型转换器,

例如,我可以很容易地做到:

代码语言:javascript
复制
public struct Tester
{
    public int Hello;

    public static implicit operator int(Tester d)
    {
        return d.Hello;
    }

    public static implicit operator float(Tester d)
    {
        return d.Hello;
    }
}

然后

代码语言:javascript
复制
typeof(Tester).GetMethods()

将返回给我隐式强制转换MethodInfo。

但是,如果我这样做了:

代码语言:javascript
复制
typeof(int).GetMethods()

它不会返回任何op_implicit。

我看到您可以看到表这里,但我想知道是否有可能从框架本身反映它。

请注意,这并不是真正的阻塞问题,如果不可能,我将手动从表中添加转换器,但我显然更希望这个动态构建(更干净、更容易出错)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-04 15:44:50

基本类型的运算符没有在框架中定义--它们是CLI本身的一部分;基本上,它们有自己的特殊指令。不涉及IL,没有方法,所以MethodInfo没有任何可参考的内容。

但是,如果您查看System.Decimal,您会发现操作符是在框架本身中实现的。

(以一种稍微类似的方式,string不声明+操作符;C#中+的使用被转换为对string.Concat的调用。)

票数 6
EN

Stack Overflow用户

发布于 2015-08-16 17:21:37

乔恩当然是对的。但是,查看一下System.Linq.Expressions.Expression类(特别是Convert方法)可能会很有用。例如,我们可以快速构建这样的东西:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Tests
{
    static class ConvertTest
    {
        // conceptual point
        static Func<TInput, TOutput> CreateConvertFunc<TInput, TOutput>()
        {
            var source = Expression.Parameter(typeof(TInput), "source");
            // the next will throw if no conversion exists
            var convert = Expression.Convert(source, typeof(TOutput));
            var method = convert.Method;
            if (method != null)
            {
                // here is your method info
            }
            else
            {
                // here is the case of primitive types
                // unfortunately it would not help you, because it's resolved when you call Complile.
                // but you can take a look at reference implementation how they handle it 
            }
            return Expression.Lambda<Func<TInput, TOutput>>(convert, source).Compile();
        }
        // cache
        struct ConverterFunc<TInput, TOutput>
        {
            public static readonly Func<TInput, TOutput> Instance = CreateConvertFunc<TInput, TOutput>();
        }
        // fluent accessor
        struct ConvertSource<T>
        {
            public T source;
            public U To<U>()
            {
                try { return ConverterFunc<T, U>.Instance(source); }
                catch (TypeInitializationException e) { throw e.InnerException; }
            }
        }
        static ConvertSource<T> Convert<T>(this T source) { return new ConvertSource<T> { source = source }; }
        // test
        struct Wrapper<T>
        {
            public T Value;
            public static implicit operator Wrapper<T>(T source) { return new Wrapper<T> { Value = source }; }
            public static implicit operator T(Wrapper<T> source) { return source.Value; }
        }
        class A { }
        class B : A { }
        static void Main(string[] args)
        {
            var v0 = 1;
            var v1 = v0.Convert().To<byte>();
            var v2 = v1.Convert().To<double>();
            var v3 = v2.Convert().To<decimal>();
            var v4 = v3.Convert().To<Wrapper<decimal>>();
            var v5 = v4.Convert().To<decimal?>();
            var v6 = v5.Convert().To<int>();
            var v7 = Enumerable.Empty<B>().Convert().To<IEnumerable<A>>();
            var v8 = v7.Convert().To<int>(); // exception
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22176415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档