2012-05-29 21 views
1

我想基於派生的設置類自動實例化正確的派生類。從相關設置類自動創建派生類?

這裏我主要的基類與基礎設置類沿

public abstract class BaseClass 
{ 
    public BaseClass() { } 

    public abstract BaseClassSettings Write(); 
} 

public class BaseClassSettings 
{ 

} 

現在,這裏是我的派生類和它們設置課程

public class DerivedFoo : BaseClass 
{ 
    public DerivedFoo(DerivedFooSettings settings) 
    { 
     // Apply settings 
    } 

    public override BaseClassSettings Write() 
    { 
     DerivedFooSettings settings = new DerivedFooSettings(); 

     return settings; 
    } 
} 

public class DerivedFooSettings : BaseClassSettings 
{ 

} 

public class DerivedBar : BaseClass 
{ 
    public DerivedBar(DerivedBarSettings settings) 
    { 
     // Apply settings 
    } 

    public override BaseClassSettings Write() 
    { 
     DerivedBarSettings settings = new DerivedBarSettings(); 

     return settings; 
    } 
} 

public class DerivedBarSettings : BaseClassSettings 
{ 

} 

我可以保存所有在派生類中設置一個陣列

DerivedFoo foo = new DerivedFoo(); 
DerivedBar bar = new DerivedBar(); 

BaseClassSettings[] s = new BaseClassSettings[2]; 
s[0] = foo.Write(); 
s[1] = bar.Write(); 

它以XML格式序列化到磁盤。

如何根據派生設置類自動實例化派生類?

所以如果數組元素是一個DerivedBarSettings類,那麼就創建一個DerivedBar類的新實例。

我想這樣做,而不是使用越來越多的其他if語句取決於類的數量。

if (BaseClassSettings is DerivedFooSettings) 
    new DerivedFoo(settings) 
else if (BaseClassSettings is DerivedBarSettings) 
    new DerivedBar(settings) 

這怎麼辦?

============================================== =================================

[編輯]

下面是我在用的:

[ 
    XmlInclude(typeof(DerivedSettingsClassA)), 
    XmlInclude(typeof(DerivedSettingsClassB)), 
    XmlInclude(typeof(DerivedSettingsClassC)), 
    XmlInclude(typeof(DerivedSettingsClassD)), 
    XmlInclude(typeof(DerivedSettingsClassE)), 
] 
public abstract class BaseSettingsClass 
{ 
    public abstract DerivedClass Load(Game1 game, OutputDimensionSettings settings); 
} 

唯一的缺點是我必須爲所有派生類明確定義XmlInclude。

回答

1

這功課嗎?

這裏有一種方法(也有其他的可能性):

public abstract class BaseClass 
{ 
    public abstract BaseClassSettings Write(); 
} 

public abstract class BaseClassSettings 
{ 
    public abstract BaseClass CreateCorrespondingInstance(); 
} 

然後:

public class DerivedFoo : BaseClass    
{    
    public DerivedFoo(DerivedFooSettings settings)    
    {    
    // Apply settings    
    }    

    public override BaseClassSettings Write()    
    {    
    DerivedFooSettings settings = new DerivedFooSettings();    
    return settings;    
    }    
}    

public class DerivedFooSettings : BaseClassSettings    
{    
    public override BaseClass CreateCorrespondingInstance() 
    { 
    return new DerivedFoo(this); 
    } 
}   

但它看起來像你可以從仿製藥受益!

+1

我可以向你保證,這不是家庭作業(除非你指望作爲功課的目標正在進行的工作,所以也許是這樣)。我正在爲我的博士項目編寫一個不是計算機科學基礎的原型。我想學習如何在這種情況下利用泛型的好處,你(或其他人)可以幫助嗎? – user1423893

0

我不確定仿製藥在這裏會有多大的幫助。泛型被用來推遲或限制一個類型,這是未知的,直到編譯時。你在做什麼是創建無關類型之間的關係。這可以通過自定義屬性和一些反射來完成。

首先我們的自定義屬性:

[System.AttributeUsage(System.AttributeTargets.Class)] 
    public class BaseClassLinkAttribute : System.Attribute 
    { 
     public System.Type LinkedType { get; set; } 

     public BaseClassLinkAttribute(Type linkedType) 
     { 
      // Probably wat to make sure type is derrived from BaseClass 
      LinkedType = linkedType; 
     } 
    } 

現在我們添加一個靜態方法來我們的基類,外幣在自定義屬性類型的實例:

public abstract class BaseClass 
{ 
    public BaseClass() 
    { 
    } 

    public abstract BaseClassSettings Write(); 

    public static BaseClass CreateFromSettings(BaseClassSettings settings) 
    { 
     Attribute attr = Attribute.GetCustomAttribute(settings.GetType(), typeof(BaseClassLinkAttribute)); 

     // Check for null here and throw exception if attribute can't be found in prduction code 

     BaseClassLinkAttribute linkAttribute = (BaseClassLinkAttribute)attr; 

     // This is only going to work if class implements a constructor 
     // that take a base settings class 

     return (BaseClass)Activator.CreateInstance(linkAttribute.LinkedType,settings); 
    } 
} 

現在我們必須do是用我們希望它創建的類的屬性標記設置類。

[BaseClassLink(typeof(DerivedFoo))] 
public class DerivedFooSettings : BaseClassSettings 
{ 
} 

所以賦予了設置類,我們現在可以創建assocated類:

 DerivedFooSettings x = new DerivedFooSettings(); 

     BaseClass y = BaseClass.CreateFromSettings(x); 

     Console.WriteLine(y.GetType().FullName); 

,這將給你Namespace.DerivedFoo的輸出。

當然,這裏有一些限制,耙類必須實現一個構造函數,該類需要設置類或激活將失敗。我認爲我們可以通過一些工作來擺脫這個問題,並通過泛型來傳遞類型。但是,您仍然必須在類型之間創建鏈接。

+0

我喜歡你的想法,我看不到需要使用泛型。我已經根據Jeppe的答案組合了我自己的一代,但我會研究你的看法,看看它是否帶來了新的東西。 – user1423893