C#:专业模板方法 - 错误:类型'...'已经定义了一个叫'...'具有相同的参数类型成员 [英] C#: specialized template method - Error: Type '...' already defines a member called '...' with the same parameter types
问题描述
我很新的C#和目前正在开发使用的EntityFramework的应用程序。我想扩展数据库上下文类的功能,这样我就可以调用方法getPool(),以便它捧出来的类的根据DbSet成员。
I'm quite new to C# and currently developing an application using the EntityFramework. I would like to extend the functionality of the database context class, so that I can call a method getPool() so that it hands out the according DbSet member of the class.
我要实现它作为一个模板,因为它会从其他模板,这是只知道对(全局)数据库上下文对象和一个T型(具有给定超类)为他们应查询数据库,供以后调用。
I need to implement it as a template as it will be later called from other templates, which are just knowing about the (global) database context object and a type T (having a given superclass) for which they shall query the database.
下面是我试了一下(有点简单化 - 原来的例子太复杂了):
Here is what I tried (a bit simplified - original example is too complicated):
public class TestContext : DbContext
{
public DbSet<TestA> ATests { get; set; }
public DbSet<TestB> BTests { get; set; }
public IQueryable<T> getPool<T>() where T : TestA {
return (IQueryable<T>)ATests;
}
public IQueryable<T> getPool<T>() where T : TestB {
return (IQueryable<T>)BTests;
}
}
该错误消息
The error message is
错误:类型'...'已经定义了一个叫'...'具有相同的参数类型
和它发生在我的模板的第二个专门定义的线(公开的IQueryable< T> getPool< T>()其中T:TESTB
)
And it occurs at the line of the second specialized definition of my template (public IQueryable<T> getPool<T>() where T : TestB
).
现在的问题是:如何来解决这个问题。
The question is: How to fix this?
推荐答案
不幸的是,在C#中,您不能使用泛型类型约束这样的重载方法。你必须给他们这样的不同的名字。
Unfortunately, in C#, you cannot overload a method by using a generic type constraint like this. You will have to give them different names like this
public class TestContext : DbContext
{
public DbSet<TestA> ATests { get; set; }
public DbSet<TestB> BTests { get; set; }
public IQueryable<T> getPoolA<T>() where T : TestA {
return (IQueryable<T>)ATests;
}
public IQueryable<T> getPoolB<T>() where T : TestB {
return (IQueryable<T>)BTests;
}
}
另一种解决办法是做这样的事情:
Another solution would be to do something like this:
public class TestContext : DbContext
{
public DbSet<TestA> ATests { get; set; }
public DbSet<TestB> BTests { get; set; }
public IQueryable<T> getPool<T>() {
return (typeof(T) == typeof(TestA))
? (IQueryable<T>)ATests
: (IQueryable<T>)BTests;
}
}
现在,你甚至可以清洁做这一点,因为< A HREF =http://msdn.microsoft.com/en-us/library/bb351562.aspx相对=nofollow> 的IQueryable< T>
在 T
是协变,你能避免铸造:
Now, you can make this even cleaner, since IQueryable<T>
is covariant in T
, you can avoid casting:
public class TestContext : DbContext
{
public DbSet<TestA> ATests { get; set; }
public DbSet<TestB> BTests { get; set; }
public IQueryable<T> getPool<T>() {
return (typeof(T) == typeof(TestA)) ? ATests : BTests;
}
}
如果你想避免类型的测试,你可以做这样的事情:
If you want to avoid testing for types you can do something like this:
public class TestContext : DbContext
{
readonly Dictionary<Type, object> _sets;
public DbSet<TestA> ATests { get; set; }
public DbSet<TestB> BTests { get; set; }
public TestContext()
{
_sets = new Dictionary<Type, object>
{
{ typeof(TestA), ATests },
{ typeof(TestB), BTests }
}
}
public IQueryable<T> getPool<T>() {
return (IQueryable<T>)_sets[typeof(T)];
}
}
这篇关于C#:专业模板方法 - 错误:类型'...'已经定义了一个叫'...'具有相同的参数类型成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!