确保 Type 实例代表可从某些 class 分配的类型

Make sure Type instance represents a type assignable from certain class

我主要是一名 Java 程序员,所以这将是 "what is this thing from Java equivalent to in C#" 问题之一。所以,在Java中,你可以在编译时限制一个Class类型的参数来扩展某个超class,像这样:

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# 中完成的?我知道你可以使用 "where T : BaseClass",但这只适用于你有一个实例 T 的情况。当你只有一个 Type 实例时呢?

编辑:

为了解释,这是我想做的:

大会 #1 (base.dll):

abstract class BaseClass {
    abstract void Foo();
}

组装 #2(sub1.dll,参考文献 base.dll):

class SubClass1 : BaseClass {
    void Foo() {
        // some code
    }
}

组装 #3(sub2.dll,参考文献 base.dll):

class SubClass2 : BaseClass {
    void Foo() {
        // some other code
    }
}

组装 #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);
}

所以,在这个例子中,我不关心 class 'type' 变量代表什么,只要它是从 BaseClass 派生的,所以一旦我创建了一个例如,可以调用 Foo().

不是有效 C# 代码的部分(而是一些 Java 模型)是 "generic" 类型 classes:Type 和 Type.

根据我的理解,你说的是 generic type constraint

public void Foo<T>(Type type) where T:BaseClass, BaseInterface1, BaseInterface2
{
    //your code
}

这里是另一篇文章:Constraints on Type Parameters (C# Programming Guide)

When you define a generic class, you can apply restrictions to the kinds of types that client code can use for type arguments when it instantiates your class. If client code tries to instantiate your class by using a type that is not allowed by a constraint, the result is a compile-time error.

编辑:

这是你的例子。现在,如果您尝试使用与 BaseClass 及其派生的 class 不同的内容调用 BaseClassUtil.CallFoo<T>,您将收到编译错误。这里full example in dotNetFiddle。所以棘手的部分是你的 class 的限制应该发生在 Util class

    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");
        }

    }

不,无法在编译时强制将 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

显然在运行时它是微不足道的,但语言在编译时不支持它。