如何根据参数?
中传递的泛型类型使此表达式动态化以简化形式:
public static class CompareService
{
public static List<T> Run<T>(List<T> database_list, string directory_path)
{
var csv_list = CompareService.MergeRecordsFromFiles<T>(directory);
return CompareService.RunComparison<T>(database_list, csv_list);
}
public static T CompareData<T>(List<T> database_list, List<T> csv_list)
{
var diff = new List<T>();
foreach (var db_item in database_list)
{
// ...
// if T is of type Deathstar compare reference_number property
// if T is of type Stormtrooper compare id property
// if T is of type Sith compare id and anger_level property
var csv_item = csv_list.FirstOrDefault(x => x.reference_number == db_item.reference_number);
// Comparison code
ComparisonResult result = compareLogic.Compare(db_item, csv_item);
// ...
}
return diff;
}
}
从另一个通用服务调用它:
public static void Whatever<T>(List<T> list)
{
// ...
var directory_path = "C:\";
var delta = CompareService.CompareData<T>(list, directory_path);
// ...
}
答案 0 :(得分:2)
最天真的实施方法是检查您的itemToFind
是否可以投放到DeathStar
,StormTrooper
或Sith
,如果是,请调用instances属性。
var deathStar = itemToFind as DeathStar;
if(deathStar != null)
return database_list.Where(x => ((DeathStar)x).reference_number == deathStar.reference_number).FirstOrDefault();
else
{
var sith = itemToFind as Sith;
if(sith != null)
return database_list.Where(x => ((Sith)x).anger_level == sith.anger_level).FirstOrDefault();
else
return database_list.Where(x => ((StormTrooper)x).id== ((StormTrooper)item).id).FirstOrDefault();
}
这很麻烦,包括很多演员阵容。特别是它完全绕过了使用任意类型的泛型的实际好处(如果存在则满足约束)。在你的情况下,你会有一个通用的方法,只会为三个不错的类型提供支持。
更好的方法是让所有类实现定义属性的公共接口,例如:
interface IObject {
int Level { get; }
}
现在所有类都定义了level
- property:
clas DeathStar : IObject
{
public int Level { get { return this.reference_number; } }
}
clas Sith : IObject
{
public int Level { get { return this.anger_level; } }
}
clas StormTrooper: IObject
{
public int Level { get { return this.id; } }
}
您可以在类型T
上使用约束来实现该接口:
public static T CompareData<T>(List<T> list, T itemToFind) where T: IObject
答案 1 :(得分:0)
为什么不喜欢这样:
public static T CompareData<T>(List<T> list, Func<T, bool> predicate)
{
return database_list.FirstOrDefault(predicate);
}
然后像这样使用它:
var itemToFind = new ItemToFind();
var myObjectList = new List<MyObject>();
var item = CompareData<MyObject>(myObjectList, x=> x.MyObjectProperty == itemToFind.Id);
答案 2 :(得分:0)
您可以添加属性选择器:
public static class CompareService
{
public static T CompareData<T>(this List<T> list, T itemToFind, Func<T, int> propSelector)
{
int propToFind = propSelector(itemToFind); // cache
return database_list.FirstOrDefault(x => propSelector(x) == propToFind);
}
}
并称之为:
listOfDeathstars.CompareData(deathStarToFind, ds => ds.reference_number);
listOfStormtroopers.CompareData(trooperToFind, t => t.id);
listOfSiths.CompareData(sithStarToFind, sith => new { sith.id, sith.anger_level});
注意:我在签名中添加了this
关键字,使其成为扩展名(不确定是否有意,但忘记了关键字)。 Where(predicate).FirstOrDefault()
可以缩减为FirstOrDefault(predicate)
。