[英]Make sure Type instance represents a type assignable from certain class
我主要是Java程序員,所以這將是“ Java等同於C#的東西”的問題之一。 因此,在Java中,您可以在編譯時限制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);
}
因此,在此示例中,我不在乎“類型”變量表示什么類,只要它是從BaseClass派生的,那么一旦創建實例,就可以調用Foo()。
不是有效的C#代碼(而是一些Java樣機)的部分是“通用”類型類:Type <T>和Type <? :BaseClass>。
據我了解,您在談論泛型類型約束
public void Foo<T>(Type type) where T:BaseClass, BaseInterface1, BaseInterface2
{
//your code
}
這是另一篇文章: 類型參數的約束(C#編程指南)
定義通用類時,可以對實例化類時客戶端代碼可用於類型參數的類型類型施加限制。 如果客戶端代碼嘗試使用約束不允許的類型實例化您的類,則結果是編譯時錯誤。
編輯:
這是你的例子。 現在,如果您嘗試使用不同於BaseClass及其派生類的方式調用BaseClassUtil.CallFoo<T>
,您將收到編譯錯誤。 這是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");
}
}
不,沒有辦法在編譯時強制將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
顯然,在運行時這很簡單,但是語言在編譯時不支持此功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.