【发布时间】:2012-02-22 01:47:19
【问题描述】:
在 C# 中可以做到这样的事情吗?
假设我有这个:
public class T : U
{
...
}
我想要这个:
public class A<T> : B<U>
{
...
}
这样我就可以在我的代码中使用它:
B<U> x = new A<T>();
【问题讨论】:
标签: c# generics inheritance
在 C# 中可以做到这样的事情吗?
假设我有这个:
public class T : U
{
...
}
我想要这个:
public class A<T> : B<U>
{
...
}
这样我就可以在我的代码中使用它:
B<U> x = new A<T>();
【问题讨论】:
标签: c# generics inheritance
你不能完全像你写的那样,但你可以这样做:
public class A<T, U> : B<U> where T : U
{
...
}
然后做
B<U> x = new A<T, U>();
【讨论】:
该初始代码确实可以正常工作...尽管由于您使用的术语可能存在一些混淆...
我相信你写的代码可以改写得更清楚如下:
void Main()
{
B<Foobar> x = new A<Wibble>();
}
// Define other methods and classes here
public class Foobar
{
}
public class Wibble : Foobar
{
}
public class B<U>
{
}
public class A<T> : B<Foobar>
{
}
要注意的关键是,有时您在泛型参数的上下文中使用 U,有时您将其用作具体类。
上面的代码(就 LINQPad 编译成的 IL 而言)等价于:
void Main()
{
B<U> x = new A<T>();
}
// Define other methods and classes here
public class U
{
}
public class T : U
{
}
public class B<U>
{
}
public class A<T> : B<U>
{
}
只有最后两个类使用泛型参数,最后一个类没有将 U 定义为泛型参数,因此它将其视为具体类。很难说这是否是您想要的,因为您没有告诉我们您想要什么,只是向我们展示了一些代码。我想您可能想要@Roy Dictus 回答的两个通用参数解决方案,但您可能想要这个。很难说。 ;-)
我应该注意,我将此答案部分归功于已删除的先前答案。该答案指出代码编译得很好,这启发了我测试实际代码。遗憾的是,由于答案被删除,我无法将灵感归功于相关人员。
谢谢大家。克里斯这解决了我的问题,前提是我能够在下面的A<T> 的构造函数中调用T 的构造函数: public class A<T> : B<Foobar> { } 我该怎么做? – jambodev 1 分钟前
在这种情况下,T 是一个泛型参数,所以你必须告诉编译器 T 绝对是可构造的。为此,您需要约束 T 以确保它具有构造函数。然后你应该能够随时创建它的新实例(例如T foo = new T();
你当然不能像链接基类的构造函数那样调用构造函数,因为 A 不以任何方式从 T 派生,它只是在其泛型模式中使用 T 类型的对象。
public class A<T> : B<Foobar> where T :new()
{
public T MyInstance {get; set;}
public A()
{
MyInstance = new T();
}
}
void Main()
{
B<Foobar> x = new A<Wibble>();
Wibble y = ((A<Wibble>)x).MyInstance;
}
(此代码替换了我第一个代码块中的等效方法)
请注意,y 是在 x 的构造函数中创建的 Wibble 类型的对象。另请注意,我需要在访问 x 之前强制转换它,因为 B<Foobar> 对泛型类型 Wibble 的使用一无所知。
【讨论】:
不完全清楚你要做什么(类名没有帮助,我的大脑正在为 T 类苦苦挣扎)。 Roy Dictus 的回答是您想要的,还是 Chris 的回答是您想要的?我以与前者不同的方式解释了这个问题,就像这样
public class MyBaseClass {}
public class MyClass : MyBaseClass {}
interface IB<out T>{}
public class B<T> : IB<T> { }
public class A<T> : B<T> {}
static void Main(string[] args)
{
IB<MyBaseClass> myVar = new A<MyClass>();
}
【讨论】: