2016-12-12 51 views
8

我主要是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#中完成的?我知道你可以使用「where T:BaseClass」,但是這隻適用於有實例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); 
} 

所以,在這個例子中,我不在乎 '型' 變量代表什麼階級,只要它是從BaseClass派生的,所以一旦我創建了一個實例,就可以調用Foo()。

不是vaild C#代碼(而是一些Java模型)的部分是「泛型」類型類型:類型< T>和類型<? :BaseClass>。

回答

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 

顯然,在運行時,它是繁瑣,但語言在編譯時間,這不支持。

2

從我瞭解你正在談論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及其派生類不同的東西調用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"); 
     } 

    } 
+0

謝謝你的回答,但我不確定它是否符合我的需求。問題部分是「類類型」部分 - 我不認爲這是有效的C#語法 - 這就是整個問題。如果是這樣,那麼這肯定會解決我的問題。但我很確定這不是... – milin

+0

@milin我給你寫了一個小例子我希望這能夠解除你的疑惑 – mybirthname

+0

我添加了一個例子,我想要做什麼 - 我覺得我的解釋不夠清楚,因爲你的例子是關於關於泛型實例,以及泛型類型實例的問題。 – milin

相關問題