我主要是一名Java程序员,所以这就是其中之一" Java中的这个东西是什么,相当于C#"的问题。因此,在Java中,您可以在编译时限制类型参数 来扩展某个超类,如下所示:
public <T extends BaseClass> void foo(Class<T> type) {
...
}
甚至
public <T extends BaseClass> T foo(Class<T> type) {
...
}
您甚至可以链接多个接口:
public <T extends BaseClass & BaseInterface1 & BaseInterface2> void foo(Class<T> type) {
...
}
这是如何在C#中完成的?我知道你可以使用&#34;其中T:BaseClass&#34;,但这只适用于你有一个实例T.当你只有一个Type实例时呢?
编辑:
有关解释,我想做的是:
ASSEMBLY#1(base.dll):
abstract class BaseClass {
abstract void Foo();
}
ASSEMBLY#2(sub1.dll,引用base.dll):
class SubClass1 : BaseClass {
void Foo() {
// some code
}
}
ASSEMBLY#3(sub2.dll,引用base.dll):
class SubClass2 : BaseClass {
void Foo() {
// some other code
}
}
ASSEMBLY#4(main.dll,引用base.dll):
class BaseClassUtil {
static void CallFoo(Type<T> type) where T : BaseClass {
T instance = (T)Activator.CreateInstance(type);
instance.Foo();
}
}
public static void Main(String[] args) {
// Here I use 'args' to get a class type,
// possibly loading it dynamically from a DLL
Type<? : BaseClass> type = LoadFromDll(args); // Loaded from DLL
BaseClassUtil.CallFoo(type);
}
所以,在这个例子中,我并不关心&#39;类型&#39;变量表示,只要它是从BaseClass派生的,所以一旦我创建了一个实例,就可以调用Foo()。
不是vaild C#代码的部分(而是一些Java模型)是&#34;泛型&#34;类型类:类型&lt; T&gt;和类型&lt;? :BaseClass&gt;。
答案 0 :(得分:2)
据我所知,你在谈论generic type constraint
public void Foo<T>(Type type) where T:BaseClass, BaseInterface1, BaseInterface2
{
//your code
}
这是另一篇文章:Constraints on Type Parameters (C# Programming Guide)
定义泛型类时,可以对其应用限制 客户端代码可用于类型参数的各种类型 实例化你的类。如果客户端代码试图实例化您的 通过使用约束不允许的类型,结果 是一个编译时错误。
修改强>
这是你的例子。现在,如果您尝试使用与BaseClass及其派生类不同的内容调用BaseClassUtil.CallFoo<T>
,您将收到编译错误。这里full example in dotNetFiddle。所以棘手的部分是你的类的限制应该在Util类
public static void Main(string[] args)
{
//so your LoadFromDll method should return Type. Type doesn't have generic implementation !
Type type = typeof(SubClass1);
BaseClassUtil.CallFoo<BaseClass>(type);
Type type2 = typeof(SubClass2);
//you can write BaseClassUtil.CallFoo<SubClass2>(type2); if you want
BaseClassUtil.CallFoo<BaseClass>(type2);
}
public class BaseClassUtil
{
public static void CallFoo<T>(Type type) where T : BaseClass
{
T instance = (T)Activator.CreateInstance(type);
instance.Foo();
}
}
public class TestClass
{
public int ID { get; set; }
}
public abstract class BaseClass
{
public abstract void Foo();
}
public class SubClass1 : BaseClass
{
public override void Foo()
{
Console.WriteLine("SubClass 1");
}
}
public class SubClass2 : BaseClass
{
public override void Foo()
{
Console.WriteLine("SubClass 2");
}
}
答案 1 :(得分:2)
不,在编译时无法强制Type
可分配给泛型类型。如果我理解正确,你想要的是:
void Foo<T>(Type type) { ... } //compile time error if an instace typed `type` is not assignable to `T`.
这意味着:
void Foo<IFormattable>(typeof(string)); //ok
void Foo<IDisposable>(typeof(string)); //compile time error
显然在运行时它很简单,但语言在编译时不支持它。