2009-09-20 19 views
1

我有一堆數據我想在一類實例化的,並且對於每個可變我要確保的方法的一個特定組也被定義。 IE:C#類的設計,而無需使用「內部」或「靜態」?

[TypeA] VarA 
[TypeB] VarB 
[TypeC] VarC 

FA1() which is a function of VarA and VarB 
FA2() which is a function of VarA and VarC 

FB1() which is a function of VarB and VarA 
FB2() which is a function of VarB and VarC 
... 

由於將有大量的變量(因此更多的功能),我想起來我的拆分源代碼轉換成可管理的塊。所以我正在尋找一種確保每個變量的所有函數都被實例化的自動方法。

我已經想出了3種可能的方法來組織我的代碼,我對他們每個人都不太滿意,我正在尋找或建議哪種方法更好(或者即使我錯過了完全不同的實現法):

1.偏類

partial class Base 
{ 
} 

partial class Base 
{ 
    [TypeA] VarA; 

    FA1 { .. }; // function of VarA and VarB 
    FA2 { .. }; // function of VarA and VarC 
} 


partial class Base 
{ 
    [TypeB] VarB; 

    FB1 { .. }; // function of VarB and VarA 
    FB2 { .. }; // function of VarB and VarC 
} 

優點:

  1. 簡單
  2. 變量只能從Base類中訪問。
  3. 如果有相同類型的兩個變量,然後每個變量的函數可以不同的方式實現其自身的功能。

缺點:

  1. 不能自動保證所有功能都爲每個變量
  2. 創建需要手動確保有每個函數名之間沒有名稱衝突。

注意,缺點可以通過某種(也許時間來學習T4?)


2.內部類

class Base 
{ 
    internal [ClassA] ObjA = new [ClassA](); 
    internal [ClassB] ObjB = new [ClassB](); 
} 

class [BaseClassA] 
{ 
    public [TypeA] VarA; 

    public virtual F1 { .. }; 
    public virtual F2 { .. }; 
} 

class [ClassA] : [BassClassA] 
{ 
    public override F1 { .. }; // function of VarA and ObjB.VarB 
    public override F2 { .. }; // function of VarA and ObjC.VarC 
} 
... 

優點代碼生成器來解決:

  1. 類層次強制執行人l函數被創建並且變量在那裏被訪問。
  2. 通過使用虛擬功能可以創建功能,例如特定實現

缺點:

  1. 使用內部意味着數據可見無處不在裝配

3。靜態數據

abstract class Data 
{ 
    static [TypeA] VarA; 
    static [TypeB] VarB; 
    ... 
} 

abstract class [BaseClassA] : Data 
{ 
    public virtual F1 { .. }; 
    public virtual F2 { .. }; 
} 

class [ClassA] : [BassClassA] 
{ 
    public override F1 { .. }; // function of VarA and VarB 
    public override F2 { .. }; // function of VarA and VarC 
} 

class Base 
{ 
[ClassA] ObjA = new [ClassA](); 
[ClassB] ObjB = new [ClassB](); 
} 

優點:

  1. 系統保證所有的程序實例化
  2. 的數據不會被炸開所有組件周圍
  3. 在每一個功能,您可以直接引用其他變量每個「部分分類」解決方案

缺點:

  1. 使用靜態聞起來就像我剛剛重新發明的全球數據。

我想要的就是以某種方式櫻桃採摘每種方法的最佳點:

  1. 訪問「部分類」的變量和「靜態」方法的直接方式
  2. 「部分類」方法的本地數據
  3. 自動實施「內部」和「靜態」方法的功能實現。

我想避免:

  1. 在「局部類」缺乏執行函數生成的
  2. 數據在「內部」方法
  3. 的再全球訪問全球數據在「靜態」方法中的發明

如果我打算讓我的druthers我會說我想要的是以某種方式將接口應用於instan一個變量,如:

[TypeA] VarA : IFunctions; 
[TypeB] VarB : IFunctions; 

並以某種方式讓編譯器自動生成接口名稱和可變名稱的最終函數名稱。

因此,人們可以建議他們希望實施哪三種方法,或建議任何其他適合的方法。

+1

ow。腦部受傷。數據是如何形成的。 – Will 2009-09-20 22:36:03

回答

0

你的問題很大程度上沒有任何真實的背景,很難理解。您提供了三個「答案」,但沒有明確的問題(imo。)

坦率地說,如果要確保每個「變量」在您調用它時都有關聯的方法,則應考慮使用接口,並使用地方字段(因爲接口不能指定字段。)

interface IAStuff { 
    TypeA AProp { get; } 
    void DoSomethingToA(); 
} 

interface IBStuff { 
    TypeB BProp { get; } 
    void DoSomethingToB(); 
} 

public class Foo : IAStuff, IBStuff { 
    TypeA AProp { get; private set; } 
    TypeB BProp { get; private set; } 

    void DoSomethingToA() { ... } 
    void DoSomethingToB() { ... } 
} 

如果類聲明它實現了一個接口,它沒有選擇,只能提供指定的成員,否則將無法編譯。

希望這有助於

-Oisin

+0

感謝您的回覆,雖然我確實相信我有一個明確的問題,我不會聲稱它必須清楚地呈現:-)但是關於您的回覆,我可以看到您來自哪裏,但是正如我寫的不要認爲它可以很好地擴展,因爲我必須爲每個變量定義一個接口(不僅僅是每種類型的變量),因此仍然需要手動維護所有方法的名稱 - 我希望能夠避開這些方法。我看不到一個通用的接口,因爲它會抽象類型,但不能抽象出方法名稱 – 2009-09-20 22:40:19

+0

如果用_class_替換該變量,那麼通用的接口或基類可能會起作用。一位聰明的老編碼員曾告訴我:如果你不能使它工作,增加更多的課程;-) – x0n 2009-09-20 23:53:18

+0

澄清,我的意思是將該領域的因素。 – x0n 2009-09-21 00:03:56

0

難道你不使用建議2,但與保護,而不是內部?

+0

我最初的反應是否定的。受保護允許從基類派生的類訪問成員。但是在這種情況下,我正在使用組合並且不從Base派生ClassA和ClassB。因此,ClassA和ClassB必須能夠獨立於Base編譯,並且我無法看到如何在沒有「Internal」的情況下執行此操作 – 2009-09-21 13:27:25

2

您提供了四個代碼示例,'簡單'版本,以便您可以解釋問題,然後解決問題3。唯一不言自明的版本是簡單版本。所以,我正在考慮那位明年要進行維護的可憐的開發人員(忘記你做了什麼之後可能是你)。

那麼,你可以考慮一個完全不同的機制:「確保每個變量的所有函數都被實例化」。您提到了在編譯期間願意使用T4爲您自動生成存根的問題。如何使用Microsoft FxCop來捕捉任何您忘記添加內容的情況。

如果您不熟悉它,Microsoft FxCop(也嵌入到某些類型的Visual Studio中)會掃描編譯後的程序集,並根據您的代碼評估數百個框架規則,從正確的拼寫和變量套管到未使用的本地代碼。

雖然我個人認同微軟捆綁到FxCop的大部分規則,但我認爲它的真正優勢在於能夠創建自己的規則。我創建了添加到FxCop中的強制執行CRUD原則的規則,例如,如果您有一個CreateXxx方法,則必須有一個DeleteXxx方法等。因此,如果您確定一個與您希望的模式匹配的類,則可以獲得一個列表所有變量{A,B,C},然後保證FuncAB(A,B)存在並且FuncAC(A,C)存在等。

然後,即使是初級開發人員也會被FxCop抓到下一個他實現了IBiVariableFunction並忘記了一對函數。

乾杯,阿德里安

+0

感謝您的答覆。我從來沒有考慮過以這種方式使用FxCop,但是我的問題更多的是不必手動生成一堆代碼,而不是在事實發生後讓FxCop告訴我「你沒有這樣做」。 至於問題的複雜性。 「簡單」版本和示例#1是相同的 - 它們僅通過使用部分類來將代碼分佈在單獨文件上而不同。另外兩個例子使用/濫用簡單的繼承來實現期望的結果 - 而不是我認爲需要深入解釋的東西。 – 2009-09-22 23:43:02

+0

有趣的是,我剛剛重新審查了你的樣本,並打破了我最初的假設之一。我原本以爲這些函數是傳遞性的,而且他們的論點。那就是FuncAB(...)和FuncBA(...)應該是相同的(例如加法而不是連接),我現在看到情況並非如此。所以,如果不考慮答案,通用接口會有幫助嗎?像IFunc 這需要Func(T,U)和Func(U,T)存在?可能會有很多接口被宣佈爲非常醜陋...... – Adrian 2009-09-23 02:05:48

+0

我不確定泛型接口會不會對我有用,但我暫時忽略了這個問題。 – 2009-09-24 20:20:12