C# 自定义扩展方法与框架扩展方法冲突。为什么?
我在我们的应用程序中有一个奇怪的行为。我想迭代一个表DataTable的行。我想使用DataTableExtensions类中的AsEnumerable扩展方法。例如:C# 自定义扩展方法与框架扩展方法冲突。为什么?,c#,datatable,extension-methods,C#,Datatable,Extension Methods,我在我们的应用程序中有一个奇怪的行为。我想迭代一个表DataTable的行。我想使用DataTableExtensions类中的AsEnumerable扩展方法。例如: foreach(var thing in table.AsEnumerable()) { ... } 当它编译时,它抱怨我需要参考一些ESRI DLLs GIS应用程序。经过一些挖掘,我从引用的DLL中找到了一些扩展方法,这些方法扩展了ESRI中的一些类型,例如IEnumField、IEnumLayer等 显然,DataTab
foreach(var thing in table.AsEnumerable())
{
...
}
当它编译时,它抱怨我需要参考一些ESRI DLLs GIS应用程序。经过一些挖掘,我从引用的DLL中找到了一些扩展方法,这些方法扩展了ESRI中的一些类型,例如IEnumField、IEnumLayer等
显然,DataTable与它们完全不同,我似乎无法找到它为什么试图绑定到AsEnumableThis IEnumLayer而不是AsEnumableThis DataTable。有趣的是,我们正在使用Resharper可怕的工具!Resharper站在我们这边:当您导航到定义时,它会将您带到对象浏览器中的一个numerableThisDataTable
我不能在这里发布大量的代码样本而不发布数千行的专有代码,所以我只是在寻找一个我曾经有过相同问题的示例,我用。。。答案的类型
显而易见的解决方案是通过删除该名称空间的所有using语句来删除对扩展方法的任何引用。但这有一个令人讨厌的副作用,那就是迫使我们完全限定任何类型声明。不漂亮
提前感谢您的任何意见
Eric。您可以使用[alias=]类或名称空间;中的alias=部分;。然后,您可以使用my=System.Data;然后将其与my.DataTable.AsEnumerable一起使用 您可以使用[alias=]类\u或\u命名空间;中的alias=部分;。然后,您可以使用my=System.Data;然后将其与my.DataTable.AsEnumerable一起使用 试试看
尝试一下……我不太清楚您为什么会遇到这个问题,但一个潜在的解决方法是放弃扩展方法语法糖,只将其视为正常的静态方法:
foreach (var thing in DataTableExtensions.AsEnumerable(table))
{
// do something
}
我不太清楚您为什么会遇到这个问题,但一个潜在的解决方法是放弃扩展方法语法糖,只将其视为正常的静态方法:
foreach (var thing in DataTableExtensions.AsEnumerable(table))
{
// do something
}
你能发布你的类层次结构吗 下面的代码显示派生最多的编译时类型扩展方法是choosen。 它是否适用于您的代码
[TestMethod]
public void Test1()
{
IEnumerable<MyCustomClass> myCustomList = new MyCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//Ignores MyCustomList method and uses IEnumerable<> method.
Assert.AreEqual(2, myCustomList.Where(x => x.Int1 > 1).Count());
}
[TestMethod]
public void Test2()
{
MyCustomList myCustomList = new MyCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//Uses MyCustomList method
Assert.AreEqual(1, myCustomList.Where(x => x.Int1 > 1).Count());
}
[TestMethod]
public void Test3()
{
ISomeInterface myCustomList = new MyCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//If your type is ISomeInterface, the compiler uses ISomeInterface method, even if the runtime instance is MyCustomList
Assert.AreEqual(0, myCustomList.Where(x => x.Int1 > 1).Count());
}
[TestMethod]
public void Test4()
{
MyDerivedCustomList myCustomList = new MyDerivedCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//Even if MyDerivedCustomList implements ISomeInterface, the compiler uses MyCustomList method
Assert.AreEqual(1, myCustomList.Where(x => x.Int1 > 1).Count());
}
[TestMethod]
public void Test5()
{
ISomeInterface myCustomList = new MyDerivedCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//If your type is ISomeInterface, the compiler uses ISomeInterface method, even if the runtime instance is MyDerivedCustomList
Assert.AreEqual(0, myCustomList.Where(x => x.Int1 > 1).Count());
}
使用此类:
public class MyCustomClass
{
public int Int1 { get; set; }
}
public class MyCustomList : List<MyCustomClass>, ISomeInterface
{
public MyCustomList() : base() { }
public MyCustomList(IEnumerable<MyCustomClass> coll) : base(coll) { }
}
public interface ISomeInterface : IEnumerable<MyCustomClass>
{
}
public class MyDerivedCustomList : MyCustomList, ISomeInterface
{
public MyDerivedCustomList() : base() { }
public MyDerivedCustomList(IEnumerable<MyCustomClass> coll) : base(coll) { }
}
public static class MyExtensions
{
/// <summary>
/// Where(x => x.Int1 > 2)
/// </summary>
public static IEnumerable<MyCustomClass> Where(this MyCustomList myList, Func<MyCustomClass, bool> predicate)
{
return new MyCustomList(Enumerable.Where(myList, predicate).Where(x => x.Int1 > 2));
}
/// <summary>
/// Where(x => x.Int1 > 3)
/// </summary>
public static IEnumerable<MyCustomClass> Where(this ISomeInterface myList, Func<MyCustomClass, bool> predicate)
{
return new MyCustomList(Enumerable.Where(myList, predicate).Where(x => x.Int1 > 3));
}
}
你能发布你的类层次结构吗 下面的代码显示派生最多的编译时类型扩展方法是choosen。 它是否适用于您的代码
[TestMethod]
public void Test1()
{
IEnumerable<MyCustomClass> myCustomList = new MyCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//Ignores MyCustomList method and uses IEnumerable<> method.
Assert.AreEqual(2, myCustomList.Where(x => x.Int1 > 1).Count());
}
[TestMethod]
public void Test2()
{
MyCustomList myCustomList = new MyCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//Uses MyCustomList method
Assert.AreEqual(1, myCustomList.Where(x => x.Int1 > 1).Count());
}
[TestMethod]
public void Test3()
{
ISomeInterface myCustomList = new MyCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//If your type is ISomeInterface, the compiler uses ISomeInterface method, even if the runtime instance is MyCustomList
Assert.AreEqual(0, myCustomList.Where(x => x.Int1 > 1).Count());
}
[TestMethod]
public void Test4()
{
MyDerivedCustomList myCustomList = new MyDerivedCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//Even if MyDerivedCustomList implements ISomeInterface, the compiler uses MyCustomList method
Assert.AreEqual(1, myCustomList.Where(x => x.Int1 > 1).Count());
}
[TestMethod]
public void Test5()
{
ISomeInterface myCustomList = new MyDerivedCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
//If your type is ISomeInterface, the compiler uses ISomeInterface method, even if the runtime instance is MyDerivedCustomList
Assert.AreEqual(0, myCustomList.Where(x => x.Int1 > 1).Count());
}
使用此类:
public class MyCustomClass
{
public int Int1 { get; set; }
}
public class MyCustomList : List<MyCustomClass>, ISomeInterface
{
public MyCustomList() : base() { }
public MyCustomList(IEnumerable<MyCustomClass> coll) : base(coll) { }
}
public interface ISomeInterface : IEnumerable<MyCustomClass>
{
}
public class MyDerivedCustomList : MyCustomList, ISomeInterface
{
public MyDerivedCustomList() : base() { }
public MyDerivedCustomList(IEnumerable<MyCustomClass> coll) : base(coll) { }
}
public static class MyExtensions
{
/// <summary>
/// Where(x => x.Int1 > 2)
/// </summary>
public static IEnumerable<MyCustomClass> Where(this MyCustomList myList, Func<MyCustomClass, bool> predicate)
{
return new MyCustomList(Enumerable.Where(myList, predicate).Where(x => x.Int1 > 2));
}
/// <summary>
/// Where(x => x.Int1 > 3)
/// </summary>
public static IEnumerable<MyCustomClass> Where(this ISomeInterface myList, Func<MyCustomClass, bool> predicate)
{
return new MyCustomList(Enumerable.Where(myList, predicate).Where(x => x.Int1 > 3));
}
}
也许以下方法最有效:
foreach (DataRow dr in table.Rows)
{
}
也许以下方法最有效:
foreach (DataRow dr in table.Rows)
{
}
我相信你可以试着写一个简短但完整的例子来说明这个问题。你所要做的就是创建一个DataTable并调用一个numerable。如果你能从编译器中发布准确的错误信息,那将非常有帮助。我相信你可以试着写一个简短但完整的例子来说明这个问题。你所要做的就是创建一个DataTable并调用一个numerable。如果你能从编译器中发布准确的错误消息,那会有很大帮助。Yuriy,你能发布一个快速的代码片段,演示如何使用扩展方法吗。我想维护table.AsEnumerable语法。我相信您建议切换到一个在我们的上下文中不那么清楚的可计算表。Yuriy,你可以发布一个简短的片段来展示如何使用扩展方法吗。我想维护table.AsEnumerable语法。我相信您建议切换到一个在我们的上下文中不那么清楚的可计算表。当做