悬赏分:50 浏览:670 次
下面两个方法ListDelete(List<BaseDT> details)和ListDelete(BaseDT[] list),这两个方法除了参数以及一小段代码不一样外,其他的都相同。各位高人谁能帮我抽象出一个方法?
我有一个思路,就是定义一个参数为Object类型或DataSet类型的委托,然后在方法中调用这个委托,总是觉得不好,希望高人能提供一个完美方案。
/// <summary>
/// 删除多条记录。
/// </summary>
/// <param name="details">记录集和</param>
public void ListDelete(List<BaseDT> details)
{
bool selfTran = false;
//事务处理
this.BeginTran();
selfTran = true;
try
{
foreach (BaseDT detail in details)
{
this.Delete(detail);
}
// 提交事务
if (selfTran)
{
this.CommitTran();
}
}
catch (Exception ex)
{
// 回滚事务
if (selfTran == true)
{
this.RollBackTran();
}
throw ex;
}
}
/// <summary>
/// 删除多条记录。
/// </summary>
/// <par
|
ListDelete(IEnumerable<BaseDT> details)
然后里面用foreach即可。
一般来说,方法的参数用越“抽象”的数据类型越好,这样可以支持更多的数据类型,增加可复用度。而方法的参数越“具体”越好,这样可以让方法的调用者更灵活地使用。
这个时候可以看一下List<BaseDT>和BaseDT[](Array类)有无共性 通过Code Definition Window可以看到 两者的共同接口有:IList, ICollection, IEnumerable 而你的方法名为ListDelete 所以用IList类型参数较好 基本上就可以…… 理由:因为两者的实现在你的代码中可以看出,只用到了参数的迭代器的特性,“最小匹配”原则一下,你可以将其指定为IEnumerable。如果有其他需求,可以再放宽要求。 测试: class GenericClass { public static void ListDelete1<T>(T list) where T : IEnumerable<IDB> { foreach (IDB item in list) { item.Delete(); } } public static void ListDelete2<T>(IEnumerable<T> list) where T : IDB { foreach (T item in list) { item.Delete(); } } public static void ListDelete3<T>(T list) where T : IEnumerable { foreach (IDB item in list) { if (item is IDB) (item as IDB).Delete(); //if (i is OtherInterface) // (item as OtherInterface).Delete(); } } public interface IDB { //Other members void Delete(); } public class BaseDT:IDB { public void Delete() { Console.WriteLine("succeed delete!"); } } class Program { static void Main(string[] args) { List<GenericClass.IDB> list1 = new List<GenericClass.IDB>(); list1.Add(new GenericClass.BaseDT()); list1.Add(new GenericClass.BaseDT()); list1.Add(new GenericClass.BaseDT()); list1.Add(new GenericClass.BaseDT()); GenericClass.ListDelete1<IEnumerable<GenericClass.IDB>>(list1); Console.WriteLine("========================"); GenericClass.IDB[] list2 = new GenericClass.IDB[] { new GenericClass.BaseDT(), new GenericClass.BaseDT(), new GenericClass.BaseDT() }; GenericClass.ListDelete1<IEnumerable<GenericClass.IDB>>(list2); Console.WriteLine("========================"); List<GenericClass.IDB> list3 = new List<GenericClass.IDB>(); list3.Add(new GenericClass.BaseDT()); list3.Add(new GenericClass.BaseDT()); list3.Add(new GenericClass.BaseDT()); list3.Add(new GenericClass.BaseDT()); GenericClass.ListDelete2<GenericClass.IDB>(list3); Console.WriteLine("========================"); GenericClass.IDB[] list4 = new GenericClass.IDB[] { new GenericClass.BaseDT(), new GenericClass.BaseDT(), new GenericClass.BaseDT() }; GenericClass.ListDelete2<GenericClass.IDB>(list4); Console.WriteLine("========================"); List<GenericClass.IDB> list5 = new List<GenericClass.IDB>(); list5.Add(new GenericClass.BaseDT()); list5.Add(new GenericClass.BaseDT()); list5.Add(new GenericClass.BaseDT()); list5.Add(new GenericClass.BaseDT()); GenericClass.ListDelete3<IEnumerable>(list5); Console.WriteLine("========================"); GenericClass.IDB[] list6 = new GenericClass.IDB[] { new GenericClass.BaseDT(), new GenericClass.BaseDT(), new GenericClass.BaseDT() }; GenericClass.ListDelete3<IEnumerable>(list6); } } 其实上面的方法也是可以的,只要你对实现IDB的方法实现自己特殊的部分,比如说: public sealed class ClassA : IDB { public string X {get;set;} public string Y {get;set;} public string IDB.GetResult() { return (X+Y); } public sealed class ClassB : IDB { public string X {get;set;} public string IDB.GetResult() { return X; } } } 这样,你统一调用Response.Write(IDB.GetResult());就可以了 这就是最基本的多态啦撒…… |
|
9个月前 Jeffrey Zhao : 不过看实现用到的是foreach,所以我还是觉得用IEnumerable好,呵呵。而且建议把方法名改成DeleteAll——.NET Framework中很多这样的命名方法。 |
|
9个月前 Jeffrey Zhao : ListDelete<T>(T list):Where T:IEnumerable 这个很奇怪,至少也应该这样吧: ListDelete<T>(IEnumerable<T> list); |
|
9个月前 volnet(可以叫我大V) : class Program { static void Main(string[] args) { List<string> list1 = new List<string>(); Console.WriteLine(GenericClass.ListDelete<List<string>>(list1)); string[] list2 = new string[] { }; Console.WriteLine(GenericClass.ListDelete<Array>(list2)); } } class GenericClass { public static string ListDelete<T>(T list) where T : IEnumerable { if (list is IEnumerable) { return "is"; } else { return "not"; } } } |
|
9个月前 Jeffrey Zhao : 范型套范型,太夸张了,尽量避免吧,呵呵。.NET中从来没有见过这样的……不知道能否通过FxCop…… |
|
9个月前 volnet(可以叫我大V) : To老赵: 其实实现方法很多的,你说的方法也都很好,我只是换个手法罢了,异曲同工…… 至于FxCop……不好说……不甚了解它的判断机制…… 不过若内部操作为类似数据库操作这样的,使用ListDelete<T>(IEnumerable<T> list);方案应该会更好吧 @楼主 随手写的未曾想太多,如果不足,楼主自行调整,提供的思路仅供参考…… |
|
9个月前 volnet(可以叫我大V) : public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable {} 这里就是泛型套泛型哦。:) |
|
9个月前 Jeffrey Zhao : 尽量避免而已,因为实在复杂,真要使用也没有办法。IDictionary的例子很合理,很清晰,应该算是良好的实现。 |
|
9个月前 Jeffrey Zhao : 忽然发现你的例子应该不可取,因为你还是没有限制了T是一个强类型的枚举,也就是方法内部是无法操作IEnumerable对象里的类型(BaseDT)的,这和lz的要求相差有些远,至少要IEnumerable<BaseDT>吧,而且这还必须看lz的要求如何。 |
|
9个月前 volnet(可以叫我大V) : TO 楼主: 看完你的问题补充,发现开始不了解你要问的意思了……(可能是理解能力比较有问题) 原来的问题貌似是在删除东西,而现在貌似没看出什么端倪来…… 而且貌似也没用到事件委托的必要…… 基于接口在这种情况下是对抽象最好的诠释,看上去这种抽象也很容易让人明白,至于泛型,在这里只是因为它可以满足对强类型的验证而显得优势倍加,至于楼主对于事件委托的应用,感觉太抽象了……起码我没看懂……汗…… 已经整理了一份新的CODE,更加完整并符合楼主想法(大概是吧),楼主看看…… |
|
9个月前 volnet(可以叫我大V) : 其实上面的方法也是可以的,只要你对实现IDB的方法实现自己特殊的部分,比如说: public sealed class ClassA : IDB { public string X {get;set;} public string Y {get;set;} public string IDB.GetResult() { return (X+Y); } public sealed class ClassB : IDB { public string X {get;set;} public string IDB.GetResult() { return X; } } } 这样,你统一调用Response.Write(IDB.GetResult());就可以了 这就是最基本的多态啦撒…… |