LiteMDA中用于实体类的Cloneable默认Generic简单实现

博客介绍了Cloneable<T>类,它实现了相关接口,可为实体类提供Clone()支持。但因基于反射,虽有缓存,性能仍受影响,对性能要求高时需手动实现接口。该类隐藏部分方法,用于实体类基类时一般不会出现克隆对象成员指向同一实例情况,其他无类型限制处慎用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类Cloneable<T>实现了LiteMDA.Common.ICloneable<T>以及System.ICloneable接口,可以作为基类为实体类提供Clone()支持。因为还是不得不基于反射,虽然加入了部分缓存,性能肯定还是会受影响,如果对性能要求较高则还需为实体类手动实现LiteMDA.Common.ICloneable<T>和System.ICloneable接口。实际的实现中,Cloneable<T>隐藏了object System.ICloneable.Clone()而只暴露T LiteMDA.Common.ICloneable<T>.Clone()。

由于实际使用中,对于应用于实体类来讲,原则上要么是值类型或者string类型,要么就必须实现LiteMDA.Common.ICloneable<T>接口,因此,用于实体类的基类时,Cloneable<T>原则上不会发生Clone出的对象内的某个成员和被Clone成员指向同一个对象实例的情况。

不过如果对于其它对类型没有以上限制的地方请慎用,一般会报错!

ICloneable.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace LiteMDA.Common
{
    
public interface ICloneable<T>
    
{
        T Clone();
    }

}


Cloneable.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace LiteMDA.Common
{
    
public abstract class Cloneable<T> : ICloneable<T>, ICloneable
        where T : 
new()
    
{
        
#region Static Cache Support

        
private static Dictionary<Type, FieldInfo[]> TypeFieldCache = new Dictionary<Type, FieldInfo[]>();

        
#endregion


        
#region ICloneable<T> Members

        
public T Clone()
        
{
            T retObj 
= new T();

            FieldInfo[] fis 
= null;
            
if (TypeFieldCache.ContainsKey(this.GetType()))
            
{
                fis 
= TypeFieldCache[this.GetType()];
            }

            
else
            
{
                fis 
= this.GetType().GetFields(BindingFlags.CreateInstance | BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.SetField);
                TypeFieldCache[
this.GetType()] = fis;
            }


            
if (fis != null && fis.Length > 0)
            
{
                
foreach (FieldInfo fi in fis)
                
{
                    
object fiValue = fi.GetValue(this);

                    
if (fi.FieldType.IsValueType)
                    
{
                        fi.SetValue(retObj, fi.GetValue(
this));
                    }

                    
else if (fiValue != null)
                    
{
                        
if (fi.FieldType == typeof(string))
                        
{
                            fi.SetValue(retObj, fiValue.ToString().Clone());
                        }

                        
else if (fi.FieldType.IsSubclassOf(Type.GetType("LiteMDA.Common.Cloneable`1").MakeGenericType(fi.FieldType)) || fiValue is ICloneable)
                        
{
                            
//if cloneable
                            fi.SetValue(retObj, fi.FieldType.GetMethod("Clone").Invoke(fiValue, null));
                        }

                        
else
                        
{
                            
throw new Exception(string.Format("Object type '{0}' is not supported by LiteMDA.Common.Cloneable<T>!", fi.FieldType.ToString()));
                        }

                    }

                    
else
                    
{
                        fi.SetValue(retObj, 
null);
                    }

                }

            }


            
return retObj;
        }


        
#endregion


        
#region ICloneable Members

        
object ICloneable.Clone()
        
{
            
return this.Clone();
        }


        
#endregion

    }

}


//文章结束
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值