C# 如果对象的所有属性在C中都为null,则将对象设置为null#
我想写一个函数,它可以转换对象的每个属性和子属性。如果一个属性的所有属性都为null,那么我会将该属性设置为null。我将用一个例子来解释 例如,如果C# 如果对象的所有属性在C中都为null,则将对象设置为null#,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我想写一个函数,它可以转换对象的每个属性和子属性。如果一个属性的所有属性都为null,那么我会将该属性设置为null。我将用一个例子来解释 例如,如果TeacherName和TeacherName都为null,那么我想将Teacher设置为null。然后,如果ExamMark和ExamName和Teacher为空,则Exam将为空 您可以从这个链接中看到类似我的问题的json版本 我写了这个方法。但这只是第一步。但我需要递归的子类。如何将此方法转换为递归? public static objec
TeacherName
和TeacherName
都为null,那么我想将Teacher
设置为null。然后,如果ExamMark
和ExamName
和Teacher
为空,则Exam
将为空
您可以从这个链接中看到类似我的问题的json版本
我写了这个方法。但这只是第一步。但我需要递归的子类。如何将此方法转换为递归?
public static object ConvertToNull(object obj)
{
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
var mainClassProperties = properties.Where(p => p.PropertyType.Assembly == objType.Assembly);
foreach (var mainClassProperty in mainClassProperties)
{
object propValue = mainClassProperty.GetValue(obj, null);
var classAllProperties = propValue.GetType().GetProperties();
if (propValue.GetType().GetProperties().All(propertyInfo => propertyInfo.GetValue(propValue) == null))
{
mainClassProperty.SetValue(obj, null);
}
}
return obj;
}
你所要求的实际上是一种反模式。它的作用是在代码中传播大量空检查的需求。您不仅需要检查所有属性是否为null,还需要检查对象在使用时是否为null。此外,反射非常慢,如果您经常这样做,您的应用程序将陷入困境
你应该调查这件事。它基本上做了您希望它做的事情,并且您删除了所有讨厌的空检查:
公共班级学生
{
公共字符串名称{get;set;}
公共字符串姓氏{get;set;}
公共广播地址{get;set;}
公开考试{get;set;}
公共静态学生NullStudent{get;}=新学生
{
Name=null,
姓氏=空,
地址=地址。空地址,
考试,
}
}
您可以对代码中以这种方式运行的每个对象执行此操作(您可以看到我也对嵌套地址和检查类型执行了此操作),然后不再执行此操作:
if(Student.EverythingIsNull){Student=null}
如果(学生为空){//do null stuff}
您可以这样做:
if(item==Student.NullStudent){//do null stuff}
这将导致代码更加清晰,您的意图更加突出,并且您可以在每个对象中明确定义构成null的内容。
你所要求的实际上是一种反模式。它的作用是在代码中传播大量空检查的需求。您不仅需要检查所有属性是否为null,还需要检查对象在使用时是否为null。此外,反射非常慢,如果您经常这样做,您的应用程序将陷入困境
你应该调查这件事。它基本上做了您希望它做的事情,并且您删除了所有讨厌的空检查:
公共班级学生
{
公共字符串名称{get;set;}
公共字符串姓氏{get;set;}
公共广播地址{get;set;}
公开考试{get;set;}
公共静态学生NullStudent{get;}=新学生
{
Name=null,
姓氏=空,
地址=地址。空地址,
考试,
}
}
您可以对代码中以这种方式运行的每个对象执行此操作(您可以看到我也对嵌套地址和检查类型执行了此操作),然后不再执行此操作:
if(Student.EverythingIsNull){Student=null}
如果(学生为空){//do null stuff}
您可以这样做:
if(item==Student.NullStudent){//do null stuff}
这将导致更清晰的代码,您的意图更加突出,并且您可以在每个对象中明确定义什么构成空值。看看这一点,GetValueOrFull应该可以工作并完成您需要的工作,没有在所有可能的用例中进行测试,但如果不能在所有情况下都工作,则可以对其进行一些调整
public static bool IsSimpleType(Type type)
{
return
type.IsPrimitive ||
new Type[] {
typeof(Enum),
typeof(String),
typeof(Decimal),
typeof(DateTime),
typeof(DateTimeOffset),
typeof(TimeSpan),
typeof(Guid)
}.Contains(type) ||
Convert.GetTypeCode(type) != TypeCode.Object ||
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) && IsSimpleType(type.GetGenericArguments()[0]))
;
}
public object GetValueOrNull(object obj)
{
if (obj == null) return null;
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
var simpleTypes = properties.Where(t => IsSimpleType(t.PropertyType));
var nonValueTypes = properties.Where(p => !simpleTypes.Contains(p));
foreach (var child in nonValueTypes)
{
child.SetValue(obj, GetValueOrNull(child.GetValue(obj)));
}
return simpleTypes.All(z => z.GetValue(obj) == null) && nonValueTypes.All(z => z.GetValue(obj) == null) ? null : obj;
}
希望它能有所帮助:)看看这个,GetValueOrFull应该可以工作并完成您需要的工作,没有在所有可能的用例中进行测试,但是如果不能在所有情况下都工作,可以对它进行一些调整
public static bool IsSimpleType(Type type)
{
return
type.IsPrimitive ||
new Type[] {
typeof(Enum),
typeof(String),
typeof(Decimal),
typeof(DateTime),
typeof(DateTimeOffset),
typeof(TimeSpan),
typeof(Guid)
}.Contains(type) ||
Convert.GetTypeCode(type) != TypeCode.Object ||
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) && IsSimpleType(type.GetGenericArguments()[0]))
;
}
public object GetValueOrNull(object obj)
{
if (obj == null) return null;
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
var simpleTypes = properties.Where(t => IsSimpleType(t.PropertyType));
var nonValueTypes = properties.Where(p => !simpleTypes.Contains(p));
foreach (var child in nonValueTypes)
{
child.SetValue(obj, GetValueOrNull(child.GetValue(obj)));
}
return simpleTypes.All(z => z.GetValue(obj) == null) && nonValueTypes.All(z => z.GetValue(obj) == null) ? null : obj;
}
希望有帮助:)使用泛型和反射
public T ConvertToNull<T>(T model) where T : class
{
if (model == null) return null;
Type type = model.GetType();
PropertyInfo[] properties = type.GetProperties();
var valueTypes = properties.Where(p => p.PropertyType.Assembly != type.Assembly);
var nonValueTypes = properties.Where(p => p.PropertyType.Assembly == type.Assembly);
foreach (var nonValueType in nonValueTypes)
nonValueType.SetValue(model, ConvertToNull(nonValueType.GetValue(model)));
if (valueTypes.All(z => z.GetValue(model) == null) && nonValueTypes.All(z => z.GetValue(model) == null))
return null;
else
return model;
}
public T ConvertToNull(T模型),其中T:class
{
if(model==null)返回null;
Type Type=model.GetType();
PropertyInfo[]properties=type.GetProperties();
var valueTypes=properties.Where(p=>p.PropertyType.Assembly!=type.Assembly);
var nonValueTypes=properties.Where(p=>p.PropertyType.Assembly==type.Assembly);
foreach(非值类型中的var非值类型)
设置值(model,ConvertToNull(nonValueType.GetValue(model));
if(valueTypes.All(z=>z.GetValue(model)==null)和&nonValueTypes.All(z=>z.GetValue(model)==null))
返回null;
其他的
收益模型;
}
在这里你可以叫它
List<Student> students = new List<Student>();
Student student = new Student() { Name = "StudentName", Surname = "StudentSurname", Address = new Address() { City = "City", Country = "Country" }, Exam = new Exam() { ExamMark = "ExamMark", ExamName = "ExamName", Teacher = new Teacher() { TeacherName = "TeacherName", TeacherSurname = "TeacherSurname" } } };
Student student2 = new Student() { Name = "StudentName", Surname = "StudentSurname", Address = new Address(), Exam = new Exam() { ExamMark = "ExamMark", ExamName = "ExamName", Teacher = new Teacher() } };
students.Add(student);
students.Add(student2);
List<Student> results = new List<Student>();
foreach (var item in students)
{
var result = ConvertToNull(item);
results.Add(result);
}
List students=newlist();
学生=新学生(){Name=“StudentName”,姓氏=“Student姓氏”,地址=新地址(){City=“City”,Country=“Country”},考试=新考试(){ExamMark=“ExamMark”,ExamName=“ExamName”,Teacher=新教师(){TeacherName=“TeacherName”,TeacherName=“Teacher姓氏”};
学生2=新学生(){Name=“StudentName”,姓氏=“Student姓氏”,地址=新地址(),考试=新考试(){ExamMark=“ExamMark”,ExamName=“ExamName”,教师=新教师()};
学生。添加(学生);
学生。添加(学生2);
列表结果=新列表();
foreach(学生中的var项目)
{
var结果=兑换券(项目);
结果。添加(结果);
}
使用泛型和反射
public T ConvertToNull<T>(T model) where T : class
{
if (model == null) return null;
Type type = model.GetType();
PropertyInfo[] properties = type.GetProperties();
var valueTypes = properties.Where(p => p.PropertyType.Assembly != type.Assembly);
var nonValueTypes = properties.Where(p => p.PropertyType.Assembly == type.Assembly);
foreach (var nonValueType in nonValueTypes)
nonValueType.SetValue(model, ConvertToNull(nonValueType.GetValue(model)));
if (valueTypes.All(z => z.GetValue(model) == null) && nonValueTypes.All(z => z.GetValue(model) == null))
return null;
else
return model;
}
public T ConvertToNull(T模型),其中T:class
{
if(model==null)返回null;
Type Type=model.GetType();
PropertyInfo[]properties=type.GetProperties();
var valueTypes=properties.Where(p=>p.PropertyType.Assembly!=type.Assembly);
var nonValueTypes=properties.Where(p=>p.PropertyType.Assembly==type.Assembly);
foreach(非值类型中的var非值类型)