Is there an Object1.CopyTo(Object2) method in .NET?
Possible Duplicate:
Cloning objects in C#
What I want to do is copy the values in a class from one object to another. Shallow Copy is just fine. However, I do not want to lose the reference that object has to the list /array/ienumerable. Also, I don't want to want to do this either:
public static void EditEvent(EventModel editEvent)
{
EventModel changingEvent = EventRepository.getEvent(editEvent.EventID);
changingEvent.Subject = editEvent.Subject;
changingEvent.EventDate = editEvent.EventDate;
changingEvent.EventDesc = editEvent.EventDesc;
changingEvent.DayCode = editEvent.DayCode;
}
But rather:
public static void EditEvent(EventModel editEvent)
{
EventModel changingEvent = EventRepository.getEvent(editEvent.EventID);
changingEvent.CopyFrom(editEvent);
//or
editEvent.CopyTo(changingEvent);
}
This is code I wrote today. It passes simple tests. I'm thinking you can use it to get started.
Here is the test:
/// <summary>
///A test for MapProperties
///</summary>
public void MapPropertiesTestHelper<S, T>(S source, T target1, bool failIfNotMatched)
{
Cake.Common.Mapper<S, T> target = new Cake.Common.Mapper<S, T>();
target.MapProperties(source, target1, failIfNotMatched);
}
[TestMethod()]
public void MapPropertiesTest()
{
var source = new Source {
OneTwo = 10,
ThreeFour = "foo"
};
var target = new Target {
OneTwo = 10,
ThreeFour = "bar"
};
MapPropertiesTestHelper<Source, Target>(source, target, true);
Assert.AreEqual(source.OneTwo, target.OneTwo);
Assert.AreEqual(source.ThreeFour, target.ThreeFour);
Assert.AreEqual(source.five_six, target.FiveSix);
}
public class Source
{
public int OneTwo { get; set; }
public string ThreeFour { get; set; }
public bool five_six { get; set; }
}
public class Target
{
public int OneTwo { get; set; }
public string ThreeFour { get; set; }
public bool FiveSix { get; set; }
}
And here is the code:
public class MapperItem
{
public MapperItem(MemberInfo member, object o)
{
this.Member = member;
this.Object = o;
}
public MemberInfo Member
{
get;
set;
}
public object Object
{
get;
set;
}
public Type Type
{
get
{
return this.Member.UnderlyingType();
}
}
public object Value
{
get
{
if (this.Member is PropertyInfo)
{
return (this.Member as PropertyInfo).GetValue(this.Object, null);
}
else if (this.Member is FieldInfo)
{
return (this.Member as FieldInfo).GetValue(this.Object);
}
else
{
throw new Exception("sourceMember must be either PropertyInfo or FieldInfo");
}
}
}
public object Convert(Type targetType)
{
object converted = null;
if (this.Value == null)
{
return converted;
}
else if (targetType.IsAssignableFrom(this.Type))
{
converted = this.Value;
}
else
{
var conversionKey = Tuple.Create(this.Type, targetType);
if (Conversions.ContainsKey(conversionKey))
{
converted = Conversions[conversionKey](this.Value);
}
else
{
throw new Exception(targetType.Name + " is not assignable from " + this.Type.Name);
}
}
return converted;
}
public void Assign(object value)
{
if (this.Member is PropertyInfo)
{
(this.Member as PropertyInfo).SetValue(this.Object, value, null);
}
else if (this.Member is FieldInfo)
{
(this.Member as FieldInfo).SetValue(this.Object, value);
}
else
{
throw new Exception("destinationMember must be either PropertyInfo or FieldInfo");
}
}
public static Dictionary<Tuple<Type, Type>, Func<object, object>> Conversions = new Dictionary<Tuple<Type, Type>, Func<object, object>>();
}
public class Mapper<S, T>
{
private List<string> ignoreList = new List<string>();
public List<string> IgnoreList
{
get { return ignoreList; }
set { ignoreList = value; }
}
public void MapProperties(S source, T target, bool failIfNotMatched = true)
{
foreach (PropertyInfo property in source.GetType()
.GetProperties()
.Where(c => !IgnoreList.Contains(c.Name)))
{
try
{
var sourceField = new MapperItem(property, source);
var targetField = new MapperItem(MatchToTarget(property), target);
targetField.Assign(sourceField.Convert(targetField.Type));
}
catch (TargetNotMatchedException noMatch)
{
if (failIfNotMatched)
{
throw noMatch;
}
}
}
}
private MemberInfo MatchToTarget(MemberInfo member)
{
List<MemberInfo> members = new List<MemberInfo>();
members.AddRange(typeof(T).GetProperties());
members.AddRange(typeof(T).GetFields());
var exactMatch = from c in members where c.Name == member.Name select c;
if (exactMatch.FirstOrDefault() != null)
{
return exactMatch.First();
}
var sameAlphaChars = from c in members
where NormalizeName(c.Name) == NormalizeName(member.Name)
select c;
if (sameAlphaChars.FirstOrDefault() != null)
{
return sameAlphaChars.First();
}
throw new TargetNotMatchedException(member, typeof(T));
}
private static string NormalizeName(string input)
{
string normalized = input.Replace("_", "").ToUpper();
return normalized;
}
}
public class TargetNotMatchedException : Exception
{
public TargetNotMatchedException(MemberInfo member, Type type)
: base("no match for member named " + member.Name + " with type named " + type.Name)
{
this.Member = member;
this.Type = type;
}
public MemberInfo Member { get; set; }
public Type Type { get; set; }
}
public static class ReflectionExtensions
{
public static Type UnderlyingType(this MemberInfo member)
{
Type type;
switch (member.MemberType)
{
case MemberTypes.Field:
type = ((FieldInfo)member).FieldType;
break;
case MemberTypes.Property:
type = ((PropertyInfo)member).PropertyType;
break;
case MemberTypes.Event:
type = ((EventInfo)member).EventHandlerType;
break;
default:
throw new ArgumentException("MemberInfo must be if type FieldInfo, PropertyInfo or EventInfo", "member");
}
return Nullable.GetUnderlyingType(type) ?? type;
}
}
You can do it like this
public class MyClonableClass : ICloneable
{
public object Clone()
{
return this.MemberwiseClone();
}
}
If you prefer to use a strongly typed method, just forget the interface
public class MyClonableClass
{
public MyClonableClass Clone()
{
return (MyClonableClass)this.MemberwiseClone();
}
}
This does not copy the fields of one object to another, but creates a new object which is an exact duplicate of the original. It makes a shallow copy.
你需要Object.MemberwiseClone方法
链接地址: http://www.djcxy.com/p/40774.html上一篇: 创建对象的深层副本