2010-07-22 34 views
1

我有混亂的情況。C#通用如何定義T是基地<Tp>:其中Tp:基地<Tp>和呼叫基地<Tp>方法

基地泛型類型和後繼

public abstract class BaseType<TEntity> : where TEntity : BaseType<TEntity> 
public class AnyType : BaseType<AnyType> 

它看起來像一個通用的循環)))

我需要的方法一樣

public void Method<T>(T data) 
{ 
if(typeof(T).IsSubclassOf(BaseType<????>)) 
convert data to BaseType<???> and exec BaseType<>'s method 
else 
//Do that 
} 

在通用的方法,我需要定義T是BaseType和exec方法就可以了。 我該怎麼做?

+0

10x for reply! 但我需要額外的功能。 public void方法(T數據) 對數據執行BaseType <>方法... 我使用反射,但我更喜歡類型轉換爲BaseType <>。 可能嗎? – sh1ng 2010-07-22 10:56:49

回答

1

您可以使用反射並使用Type.BaseType在層次結構上工作。注意,根據確切的具體類別,基本類型仍然可以是開放的泛型類型,例如,

class Foo<T> : BaseType<T> 

您可以使用Type.IsGenericTypeDefinitionType.GetGenericTypeDefinition嘗試用自己的方式工作,以BaseType<>。基本上你想知道繼承層次結構中的任何類是否有一個泛型類型定義,即typeof(BaseType<>)。只是很高興你不處理接口,使整個事情就更難了:)

+0

10x爲答覆!但我需要額外的功能。 public void Method (T data)Exec BaseType <>方法上的數據...我用我的反射,但我更喜歡類型轉換爲BaseType <>。可能嗎? – sh1ng 2010-07-22 11:28:22

+0

@ sh1ng:這不太清楚你的意思。也許你應該使用'Method '(TBase值),其中TBase:BaseType '? – 2010-07-22 11:49:21

+0

我不能將類型約束添加到泛型方法... 如果數據(參數)爲BaseType ,則調用 ((BaseType )data).Method() else other actions .... ((BaseType )數據中的問題) 類型'T'不能用作泛型類型或方法'BaseType '中的類型參數'TEntity'。有一個從「T」沒有裝箱轉換或類型參數轉換爲「BASETYPE 」 其實我需要轉換噸至「B :其中T:乙」 – sh1ng 2010-07-22 12:22:18

1

您可以使用下面的代碼:

static bool IsBaseType<T>() 
{ 
    var t = typeof(T); 

    do 
    { 
     if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(BaseType<>)) 
     { 
      return true; 
     } 

     t = t.BaseType; 
    } 
    while (t != null); 

    return false; 
} 
+0

10x爲答覆!但我需要額外的功能。 public void Method (T data)Exec BaseType <>方法上的數據...我用我的反射,但我更喜歡類型轉換爲BaseType <>。可能嗎? – sh1ng 2010-07-22 11:29:19

0

在這種情況下,一個常見的模式是有一個非泛型基類型的泛型基類型。如果你的方法不涉及類型參數,那麼你就完成了。如果是這樣,你可以,做一個類型轉換爲非泛型方法,類似添加的Object.Equals:

public abstract class ReallyBaseType 
{ 
    public abstract void SomeMethod(); 
    public abstract void SomeMethodWithParameter(object o); 
} 

public abstract class BaseType<TEntity> : ReallyBaseType 
    where TEntity : BaseType<TEntity> 
{ 
    public override void SomeMethodWithParameter(object o) 
    { 
     SomeMethodWithParameter((TEntity)o); 
    } 

    public abstract void SomeMethodWithParameter(TEntity entity); 
} 

public class AnyType : BaseType<AnyType> 
{ 
    public override void SomeMethod() { } 

    public override void SomeMethodWithParameter(AnyType entity) { } 
} 

然後,你可以檢查實際數據類型:

public void Method<T>(T data) 
{ 
    if (data is ReallyBaseType) 
    { 
     ((ReallyBaseType)(object)data).SomeMethod(); 
    } 
} 

編輯:我覺得你卡住了反射,然後。如果您希望能夠針對具體類型編寫代碼,則可以創建通用方法並使用反射調用它:

public class TestClass 
{ 
    private static MethodInfo innerMethodDefinition = 
     typeof(TestClass).GetMethod("InnerMethod"); 

    public void Method(object data) 
    { 
     var t = data.GetType(); 
     while (t != null && 
      !(t.IsGenericType && 
      t.GetGenericTypeDefinition() == typeof(BaseType<>))) 
     { 
      t = t.BaseType; 
     } 
     if (t != null && 
      t.GetGenericArguments()[0].IsAssignableFrom(data.GetType())) 
     { 
      innerMethodDefinition.MakeGenericMethod(
       t.GetGenericArguments()[0]).Invoke(this, new object[] { data }); 
     } 
    } 


    public void InnerMethod<TEntity>(TEntity data) 
     where TEntity : BaseType<TEntity> 
    { 
     // Here you have the object with the correct type 
    } 
} 
+0

我知道,但它是在當前項目(((( – sh1ng 2010-07-22 12:03:20