2012-08-26 40 views
1

我有一個接口IDatabase,它以幾種不同的方式訪問數據庫。例如使用RESTful或MySqlDirectConnect。在C中使用泛型變量的可能性#

接下來我有一個類foo有成員變量A,B,C需要從數據庫中拉出數據。

public class foo 
{ 
    private string a; 
    private int b; 
    private int c; 
} 

本來,我打算創建爲每一個成員變量get方法。使用泛型,您可以指定要使用的接口。

public string GetA<T>() where T: IDatabase 
{ 
    //example might be GetA<RESTful>(); 
} 

public int GetB<T>() where T: IDatabase 
{ 
    //example might be GetB<MySQL>(); 
} 

等等....

問題,我看到的是,如果對數據庫的修改我要回去和更改所有這些方法。在某些情況下,foo類可能會有大約20個變量,每個變量都有一個Get()方法。

所以我想創建一個真正通用的GetValue(),我可以指定接口和我想要查詢的變量。

東西沿着線:

public object GetValue<T>(the class variable I want to query) where T: IDatabase 
{ 
    //query database using type T and return it to the variable specified 
} 

我想避免具有用於該方法內的每個成員變量條件。

這是可能的嗎?

回答

0

這裏是一個偉大的解決方案,我摸索出

public void GetValue<T>(string property) where T: IDatabase, new() 
{ 
    IDatabase database = new T(); 
    database.RegisterObserver(this); 

    string FROM = typeof(theCurrentClass).Name; 
    string SELECT = editProperty = property; 
    string WHERE = "1"; 

    database.Select(new Query(SELECT, FROM, WHERE));   
} 

private string fieldName; //contains the name of the field I want to edit 

void IObserver.Update(object data) 
{  
    FieldInfo field = this.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); 

    if(field != null) 
    { 
     field.SetValue(this, data);   
    } 
} 

編輯:我終於想通了,只是更新了最終答案上面的代碼

1

泛型在這裏似乎不太適合。你想一個接口IDatabase(如你),它有多種實現:RestfulDbMySqlDb

可以了IDatabase然後有一個方法:object GetValue(string name)你提供從IDatabase派生每個類的具體實現這一點。

如果您使用的是泛型,那麼GetValue<T>中的代碼將如何知道您希望繼承哪個MySql數據庫實例 - 它只是一個類型。

您可能想了解像NHibernat e這樣的項目如何處理此問題。

+0

將這項工作?(雖然我承認它未經測試) 'public void GetA ()其中T:IDatabase,new() IDatabase database = new T(); a = database.Select(new Query(「something1」,「something2」,「something3」)); return a; \t \t }' – MichaelTaylor3D

+0

對不起,我無法得到這個格式正確 – MichaelTaylor3D

0

聲明一個接口:

public interface IDataProvider<T> 
{ 
    T Get() 
} 

然後實現每個數據源和類類型一個提供商

public class FootRestProvider : IDataProvider<Foo> 
{ 
    public Foo Get() 
    { 
     // implement logic to get foos from rest 
    } 
} 

public class FooMySqlProvider : IDataProvider<Foo> 
{ 
    public Foo Get() 
    { 
     // implement logic to get foos from mysql 
    } 
} 

最後,如果富的特性來自不同的來源;合併它們在另一個類:

public class FooMerger 
{ 
    // fill this list from constructor 
    private IList<IDataProvider<Foo>> providers; 

    public Foo Get() 
    { 
     var foosToMerge = providers.Select(x => x.Get()). 

     // implement merging logic here 
    } 
} 
+0

它似乎沒有選擇是一個有效的方法爲IList,你可以進一步闡述? – MichaelTaylor3D

+0

Select是在System.Linq命名空間中聲明的擴展方法:http://msdn.microsoft.com/en-us/library/bb548891.aspx – mathieu

+0

哦,是的,我有多愚蠢:P – MichaelTaylor3D