赞
踩
现用户提出这样个需求,其拿到一个只读属性值(只有get方法,没有set),如何强行修改这个属性的值呢?
这里的属性可以是单值,常见的string,float,double etc,可以是List 对象集合属性。
现对Product下的Id属性和Detail属性值进行修改。
根据对于属性原来的值和属性值类型其存在两种情况:
1 属性值为空时,单值、List集合操作为均为append追加操作;
2 属性值不为空,操作分两种:对于单值,进行modify操作;对于多值,需要定位到具体索引,同时可以通过startIndex和length来定位modify操作的长度。
- class Product
- {
- public string Id { get;}//只读,不可写
- public string Name { get; set; }
- public List<ProductDetail> Detail { get; }//只读,不可写
-
- public List<ProductComment> Comment { get; set; }
- }
- class ProductDetail
- {
- public string DtlId { get; set; }
- public string Id { get; set; }
- public decimal Number { get; set; }
- public decimal Price { get; set; }
- public decimal Amount { get; set; }
- }

传入instance对象,在ModifyFieldsValue方法中通过反射获取到指定membername的成员信息。
通过pinfo.CanWrite属性值判断其是否可写,当不可写时,通过newType.GetRuntimeFields()拿到其私有字段值。
调用SetListValueInField方法通过判断MemberInfo具体为PropertyInfo或FieldInfo,来将list数据装载到instance对应的属性上。
- static void Main(string[] args)
- {
- var instance = new Product();
- var DetailListBefore = new List<ProductDetail>
- {
- new ProductDetail{Id="000" ,DtlId="1",Number=12.3568M,Price=5.689M,Amount=70.2978352M},
- new ProductDetail{Id="000",DtlId="2",Number=12.35M,Price=5.689M,Amount=70.2978352M},
- new ProductDetail{Id="000",DtlId="3",Number=12.358M,Price=5.689M,Amount=70.304662M},
- };
- //instance.Detail = DetailListBefore;
-
- var DetailListAfter = new List<ProductDetail>
- {
- new ProductDetail{Id="111" ,DtlId="4",Number=12.3568M,Price=5.689M,Amount=70.2978352M},
- new ProductDetail{Id="111",DtlId="5",Number=12.35M,Price=5.689M,Amount=70.2978352M},
- new ProductDetail{Id="111",DtlId="6",Number=12.358M,Price=5.689M,Amount=70.304662M},
- };
- MethodHelper.ModifyFieldsValue<Product, string>(instance, "Id", "1000");
- MethodHelper.ModifyFieldsValue<Product, ProductDetail>(instance, "Detail", null, DetailListAfter, true, 0, 3);
- Console.WriteLine(instance.Id);
-
- instance.Detail.ForEach(a => { Console.WriteLine(a.DtlId); });
- Console.WriteLine("----------------------------");
- Console.ReadKey();
- }
-
- //MethodHelper类
- /// <summary>
- /// 修改实例对应只读或可读写属性的值
- /// </summary>
- /// <typeparam name="T">实例对象类型</typeparam>
- /// <typeparam name="S">属性类型</typeparam>
- /// <param name="instance">实例对象</param>
- /// <param name="membername">属性名</param>
- /// <param name="Singlevalue">赋予的单值</param>
- /// <param name="assignlist">赋予的List值</param>
- /// <param name="appendOrReplace">对于泛型集合属性,appendOrReplace为true,单值默认为false</param>
- /// <param name="StartIndex">>对于泛型集合属性,赋予list新值在原List的StartIndex索引,默认为-1</param>
- /// <param name="length">索引长度,默认为0</param>
- public static void ModifyFieldsValue<T, S>(T instance, string membername, object Singlevalue = null, List<S> assignlist = null, bool appendOrReplace = false, int StartIndex = -1, int length = 0)
- {
- var newType = instance.GetType();
- var pInfo = newType.GetRuntimeProperties().FirstOrDefault(p => p.Name == membername);
- if (pInfo != null && pInfo.CanWrite)
- {
- if (appendOrReplace)
- {
- List<S> fVal = (List<S>)pInfo.GetValue(instance);
- //原List属性没有值时:
- if (fVal == null)
- {
- SetListValueInField(instance, assignlist, pInfo);
- }
- //原List属性存在值时:
- else
- {
- AppendOrReplaceList(assignlist, StartIndex, length, fVal);
- pInfo.SetValue(instance, fVal);
- }
- }
- else
- {
- //(S)Convert.ChangeType(Singlevalue, typeof(S))
- pInfo.SetValue(instance, Singlevalue);
- }
- }
- else if (pInfo != null)
- {
- var backFildInfo = newType.GetRuntimeFields().FirstOrDefault(f => f.Name.Contains($"<{membername}>") && f.Name.Contains("BackingField"));
- if (appendOrReplace)
- {
- List<S> fVal = (List<S>)backFildInfo.GetValue(instance);
- if (fVal == null)
- {
- SetListValueInField(instance, assignlist, backFildInfo);
- }
- else
- {
- AppendOrReplaceList(assignlist, StartIndex, length, fVal);
- }
- }
- else
- {
- backFildInfo.SetValue(instance, Singlevalue);
- }
- }
- else
- {
- return;
- }
-
- }
-
- private static void AppendOrReplaceList<S>(List<S> assignlist, int StartIndex, int length, List<S> fVal)
- {
- if (fVal.Count < length || fVal.Count < assignlist.Count)
- {
- throw new Exception("传入的length值或assignlist不对,其应小于或等于原集合长度");
- }
- if (StartIndex != -1 && length > 0)
- {
- for (int index = 0; index < length; index++)
- {
- fVal[StartIndex + index] = assignlist[index];
- }
- }
- }
-
- private static void SetListValueInField<T, S>(T instance, List<S> assginlist, MemberInfo pInfo)
- {
- var type1 = typeof(List<>);
- if (pInfo is PropertyInfo)
- {
- type1 = type1.MakeGenericType((pInfo as PropertyInfo).PropertyType.GenericTypeArguments.First());
- object instanceVal = CreateInstanceWithList(assginlist, type1);
- (pInfo as PropertyInfo).SetValue(instance, instanceVal);
- }
- if (pInfo is FieldInfo)
- {
- type1 = type1.MakeGenericType(((pInfo as FieldInfo)).FieldType.GenericTypeArguments.First());
- object instanceVal = CreateInstanceWithList(assginlist, type1);
- (pInfo as FieldInfo).SetValue(instance, instanceVal);
- }
- }
-
- private static object CreateInstanceWithList<S>(List<S> assginlist, Type type1)
- {
- var instanceVal = Activator.CreateInstance(type1);
- var add = type1.GetMethod("Add", type1.GetGenericArguments());
- foreach (var obj in assginlist)
- {
- List<object> parametersList = new List<object>();
- parametersList.Add(obj);
- add.Invoke(instanceVal, parametersList.ToArray());
- }
- return instanceVal;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。