设计类型

2019-03-03  本文已影响0人  沈_ac89

设计类型

一、类型基础

常见问题

  1. 面向对象语言的特点?
  1. var o = new object(); // CLR背后帮我们做了哪些事情?
    
    • 计算类型及其所有基类型(一直到System.Object)中所有的实例字段需要的字节数。注意,堆上每个对象都需要一些额外的成员,当中包含额外成员(类型对象指针(type object pointer)和同步块索引(sync block index))占用的字节数。
    • 从托管堆中分配类型要求的字节数。
    • 初始化对象的“类型对象指针”和“同步块索引”成员。
    • 非静态类初始化:调用类型的实例构造器,传递在new调用中指定的实参,一般构造函数中会自动生成代码来自动调用基类构造器。
    • 返回指向该对象的一个引用(或指针)。
  2. is和as使用存在的坑点。

  1. 命名空间和程序集的关系?
  1. “运行时”的相互关系(参考堆栈的内存分配

专业名词

类型对象指针

同步块

来自横刀天笑syncblock_thumb.png

同步块索引

​ 同步索引是每个堆内对象都会分配的一个字段。

参考内容

二、基元类型、引用类型和值类型

基元类型

编译器直接支持的类型成为基元类型(Primitive Type),能直接映射到FCL中存在的类型。

常见问题

引用类型和值类型

常见问题

声明为值类型的前提条件

​ 优势是不作为对象在托管对上的分配。

字段布局

​ 使用StructLayoutAttribute特性,FieldOffsetAttribute特性指出字段第一个字节举例实例起始处的偏移量。

装箱和拆箱
Equals和GethashCode重载
Equals
    /// <summary>
    /// 自定义对象类型重写
    /// </summary>
    public class A : IEquatable<A>
    {

        public string Id { get; set; }

        // 实现IEquatable接口
        public bool Equals(A other)
        {
            // 为空,肯定不相等
            if (ReferenceEquals(null, other)) return false;
            // 同一对象,必然相等
            if (ReferenceEquals(this, other)) return true;
            // 比较各个字段
            if (!string.Equals(this.Id, other.Id, StringComparison.InvariantCulture))
            {
                return false;
            }
            return true;
        }

        public override bool Equals(object obj)
        {
            //this非空,obj如果为空,则返回false
            if (ReferenceEquals(null, obj)) return false;
            //如果为同一对象,必然相等
            if (ReferenceEquals(this, obj)) return true;
            //如果类型不同,则必然不相等
            if (obj.GetType() != this.GetType()) return false;
            //调用强类型对比
            return Equals((A)obj);
        }

        public override int GetHashCode()
        {
            return this.Id == null ? 0 : StringComparer.InvariantCulture.GetHashCode(this.Id);
        }

        // 重写==号
        public static bool operator ==(A left, A right)
        {
            return Equals(left, right);
        }

        // 重载!=号
        public static bool operator !=(A left, A right)
        {
            return !Equals(left,right);
        }

    }

    /// <summary>
    /// ValueType类型比较
    /// 注意:int?这种还是ValueType类型,注意**可为空**)。
    /// </summary>
    public struct B : IEquatable<B>
    {
        private string _id;

        public B(string id)
        {
            this._id = id;
        }

        public bool Equals(B other)
        {
            // 比较字段是否相等
            return string.Equals(this._id,other._id,StringComparison.InvariantCulture);
        }

        public override bool Equals(object obj)
        {
            // 为空不相等
            if (ReferenceEquals(null, obj)) return false;
            return obj is B && Equals((B)obj);
        }

        public override int GetHashCode()
        {
            return (this._id != null) ? StringComparer.InvariantCulture.GetHashCode(_id) : 0;
        }

        public static bool operator ==(B left,B right)
        {
            if (left == null && right == null)
                return true;
            if (left == null)
                return right.Equals(left);
            return left.Equals(right);
        }

        public static bool operator !=(B left, B right)
        {
            if (left == null && right == null)
                return false;
            if (left == null)
                return !right.Equals(left);
            return !left.Equals(right);
        }
    }

HashCode
dynamic(比较重要,后续补充完整)

Visual C# 2010 引入了一个新类型 dynamic。 该类型是一种静态类型,但类型为 dynamic 的对象会跳过静态类 型检查。 大多数情况下,该对象就像具有类型 object 一样。 在编译时,将假定类型化为 dynamic 的元素支持任何操作。 因此,您不必考虑对象是从 COM API、从动态语言(例如 IronPython)、从 HTML 文档对象模型 (DOM)、从反射还是从程序中的其他位置获取自己的值。 但是,如果代码无效,则在运行时会捕获到错误。

参考范例(继续改进)
    /// <summary>
    /// 适用于4.5版本或以上
    /// </summary>
    public class StaticMemberDynamicWrapper : DynamicObject
    {
        private readonly TypeInfo _typeInfo;

        public StaticMemberDynamicWrapper(Type type)
        {
            this._typeInfo = type.GetTypeInfo();
        }

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return this._typeInfo.DeclaredMembers.Select(p => p.Name);
        }

        /// <summary>
        /// 获取字段或者属性的值
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = null;
            var field = FindField(binder.Name);
            if (field != null)
            {
                result = field.GetValue(null);
                return true;
            }
            var prop = FindProperty(binder.Name, true);
            if (prop != null)
            {
                result = prop.GetValue(null,null);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 设置属性或者字段值
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            var field = FindField(binder.Name);
            if (field != null)
            {
                field.SetValue(null, value);
                return true;
            }
            var prop = FindProperty(binder.Name, true);
            if (prop != null)
            {
                prop.SetValue(null,value,null);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 调用方法
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="args"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            MethodInfo methodInfo = FindMethodInfo(binder.Name,args.Select(p=> p.GetType()).ToArray());
            if (methodInfo == null)
            {
                result = null;
                return false;
            }
            result = methodInfo.Invoke(null, args);
            return true;
        }

        /// <summary>
        /// 寻找方法
        /// </summary>
        /// <param name="name"></param>
        /// <param name="types"></param>
        /// <returns></returns>
        private MethodInfo FindMethodInfo(string name, Type[] types)
        {
            return _typeInfo.DeclaredMethods.FirstOrDefault(p => p.Name == name && p.IsPublic && p.IsStatic && ParametersMatch(p.GetParameters(), types));
            
        }

        /// <summary>
        /// 方法参数类型比较
        /// </summary>
        /// <param name="parameterInfos"></param>
        /// <param name="types"></param>
        /// <returns></returns>
        private bool ParametersMatch(ParameterInfo[] parameterInfos, Type[] types)
        {
            if (parameterInfos == null || parameterInfos.Length <= 0)
            {
                return false;
            }
            for (int i = 0; i < types.Length; i++)
            {
                if (parameterInfos[i].ParameterType != types[i])
                    return false;
            }
            return true;
        }

        /// <summary>
        /// 寻找属性
        /// </summary>
        /// <param name="name"></param>
        /// <param name="get"></param>
        /// <returns></returns>
        private PropertyInfo FindProperty(string name, bool get)
        {
            if (get)
            {
                return _typeInfo.DeclaredProperties.FirstOrDefault(p => p.Name == name && p.GetMethod != null && p.GetMethod.IsPublic && p.GetMethod.IsStatic);
            }
            return _typeInfo.DeclaredProperties.FirstOrDefault(p => p.Name == name && p.SetMethod != null && p.SetMethod.IsPublic && p.SetMethod.IsStatic);
        }

        /// <summary>
        /// 寻找字段
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private FieldInfo FindField(string name)
        {
            return this._typeInfo.DeclaredFields.FirstOrDefault(p => p.IsPublic && p.IsStatic && p.Name.Equals(name));
        }

    }
    
    /// <summary>
    /// 测试
    /// </summary>
    public class DyamicObjectTest
    {
        public void Run()
        {
            dynamic stringType = new StaticMemberDynamicWrapper(typeof(string));
            var result = stringType.Concat("A", "B");
            // 运行报错
            //dynamic stringType2 = "";
            //var result2 = stringType2.Concat("B", "C");
            //Console.Write(result2);
            dynamic sampleObject = new ExpandoObject();
            sampleObject.Concat = (Func<string,string,string>)((c, d) => { return c + d; });
            var result3 = sampleObject.Concat("A", "B");
            Console.WriteLine(result3);
            Console.Write(result);
        }
    }

参考内容

上一篇下一篇

猜你喜欢

热点阅读