我有一个案例我想比较c#中的两个对象。同样我可以选择在比较时排除特定属性。任何人都可以提出更好的方法。课程如下所示
public class Address
{
public string AddressID { get; set; }
public int AddressStagingID { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string Postcode { get; set; }
public string Country { get; set; }
public bool PreferredAddress { get; set; }
public int? DBID { get; set; }
public Enum AddressStatus Status { get; set; }
}
我需要一个像
这样的功能private bool IsAddressModified(Address currentAddress,Address existingAddress)
{
}
答案 0 :(得分:2)
如果您正在寻找非常简单的东西,请使用反射。但如果您需要某些高级功能,请使用CompareObjects。这是Nuget。该库还可以提供有关更改的详细报告。这意味着你可以用它来记录等。
这是该网站的示例代码。
//This is the comparison class
CompareLogic compareLogic = new CompareLogic();
//Create a couple objects to compare
Person person1 = new Person();
person1.DateCreated = DateTime.Now;
person1.Name = "Greg";
Person person2 = new Person();
person2.Name = "John";
person2.DateCreated = person1.DateCreated;
ComparisonResult result = compareLogic.Compare(person1, person2);
//These will be different, write out the differences
if (!result.AreEqual)
Console.WriteLine(result.DifferencesString);
答案 1 :(得分:1)
反思怎么样:
private bool IsAddressModified(Address currentAddress, Address existingAddress)
{
foreach (PropertyInfo pi in currentAddress.GetType().GetProperties())
{
//To exclude properties use condition
if (pi.Name != "City") {
object currentElement = typeof(Address).GetProperty(pi.Name).GetValue(currentAddress,null);
object existingElement = typeof(Address).GetProperty(pi.Name).GetValue(existingAddress,null);
if (!currentElement.Equals(existingElement))
{ return false; }
}
return true;
}
}
答案 2 :(得分:1)
我尝试使用表达式树开发一个不同的解决方案,在我看来,这是更灵活的
public class Test
{
public static void Main()
{
Address a1 = new Address();
a1.AddressID = "100";
Address a2 = new Address();
a2.AddressID = "200";
Console.WriteLine(IsAddressModified(a1,a2,a=>a.AddressID));
}
public static bool IsAddressModified(Address a1,Address a2,params Expression<Func<Address,Object>>[] props)
{
if(props == null)
return a1.Equals(a2);
foreach(Expression<Func<Address,object>> memberExpression in props)
{
MemberExpression property = memberExpression.Body as MemberExpression;
if(property != null)
{
foreach(PropertyInfo pi in typeof(Address).GetProperties())
{
// exclude all properties we passed in
if(!pi.Name.Equals(property.Member.Name))
{
var valueA1 = pi.GetValue(a1);
var valueA2 = pi.GetValue(a2);
if(valueA1 != null && valueA2 != null)
if(!valueA1.Equals(valueA2))
return true;
}
}
}
}
return false;
}
}
那么代码是什么?
IsAddressModified
。比较时将排除这些属性。Address
类型的所有属性,并检查它是否是要排除的属性。使用此解决方案,您可以根据需要将尽可能多的属性传递给函数。在编译期间,您完全是类型安全的。
在Main中你可以看到我如何调用这个函数。即使AddressID
a1
和a2
的{{1}}不同,该函数也会返回false,因为您排除了AddressID
。
可以找到完整的可编辑示例here
答案 3 :(得分:0)
蛮力?
private bool IsAddressModified(Address a, Address b)
{
return a.Address1 != b.Address1 || a.Address2 != b.Address2
|| a.City != b.City || a.PostCode != b.PostCode;
// etc. for all the properties that are considered as modified
}
答案 4 :(得分:0)
Compare NET Objects拥有您所需的一切!
按表达式忽略
const path = require('path');
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
mode: "development",
entry: './src/index.js',
devtool: 'inline-source-map', // for development build only
devServer: {
contentBase: './dist',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js', // for development build only
// filename: '[name].[contenthash].js', // for production build only
},
plugins: [
new CompressionPlugin({
filename: "[path].gz[query]",
algorithm: "gzip",
test: /\.(js|css|html|svg)$/
})
],
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
},
{
test: /\.s[ac]ss$/i,
use: [
'style-loader', // Creates `style` nodes from JS strings
'css-loader', // Translates CSS into CommonJS
'sass-loader', // Compiles Sass to CSS
],
},
]
}
};
忽略ClassName.MemberName
CompareLogic compare = new CompareLogic();
compare.Config.IgnoreProperty<Person>(x => x.Name);
忽略所有具有名称的成员
CompareLogic compare = new CompareLogic();
compare.Config.MembersToIgnore.Add("Person.Name");
使用通配符忽略
CompareLogic compare = new CompareLogic();
compare.Config.MembersToIgnore.Add("UpdateDate");
忽略属性
CompareLogic compare = new CompareLogic();
compare.Config.MembersToIgnore.Add("*Id");
仅比较具有属性的属性
[AttributeUsage(AttributeTargets.Property)]
public sealed class CompareIgnoreAttribute : Attribute
{
}
public class Shipment
{
public long IdentCode { get; set; }
public String Customer { get; set; }
[CompareIgnore]
public DateTime InsertDate { get; set; }
}
CompareLogic compare = new CompareLogic();
compare.Config.AttributesToIgnore.Add(typeof(CompareIgnoreAttribute));