确保Type实例表示可从特定类分配的类型

时间:2016-12-12 13:01:11

标签: java c# types extends

我主要是一名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;。

2 个答案:

答案 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

显然在运行时它很简单,但语言在编译时不支持它。