2009-01-21 62 views
2

我有這種方法Verify_X在數據綁定期間爲列表框選定的值調用。問題是強類型數據源。我想使用抽象類BaseDataSource或一個接口來調用支持的方法: Parameters []和Select(),而不是使用最具體的實現,如下所示。使用泛型時將類轉換成抽象類或接口

這是一種方法可以用於所有不同類型的數據源我有,而不是每個有一個方法。他們都以同樣的方式繼承。

這裏是繼承/實現的鏈條

public class DseDataSource : ProviderDataSource<SCCS.BLL.Dse, DseKey> 

public abstract class ProviderDataSource<Entity, EntityKey> : BaseDataSource<Entity, EntityKey>, ILinkedDataSource, IListDataSource 
    where Entity : SCCS.BLL.IEntityId<EntityKey>, new() 
    where EntityKey : SCCS.BLL.IEntityKey, new() 

public abstract class BaseDataSource<Entity, EntityKey> : DataSourceControl, IListDataSource, IDataSourceEvents 
    where Entity : new() 
    where EntityKey : new() 

的BaseDataSource有我需要的方法和屬性。 DseDataSource實現方式如下:

public class DseDataSource : ProviderDataSource<SCCS.BLL.Dse, DseKey> 

我知道它是可以編輯類DseDataSource,添加接口接入參數[],然後選擇(),然後針對該程序,它允許我想要的,但這需要編輯NetTiers庫,我很好奇看看是否可以完成,因爲看起來很困難。

public static string Verify_DSE(string valueToBind, DseDataSource dataSource) 
    { 
     if (ListContainsValue(dataSource.GetEntityList(), valueToBind)) return valueToBind; 
     CustomParameter p = dataSource.Parameters["WhereClause"] as CustomParameter; 
     if (p != null) 
     { 
      p.Value = "IsActive=true OR Id=" + valueToBind; 
      dataSource.Select(); 
      return valueToBind; 
     } 
     return string.Empty; 
    } 

    private static bool ListContainsValue(IEnumerable list, string value) 
    { 
     if (value.Length == 0) return true; 

     foreach (object o in list) 
     { 
      IEntity entity = o as IEntity; 
      if (entity != null) 
      { 
       if (entity.Id.ToString() == value) 
        return true; 
      } 
     } 
     return false; 
    } 

最終的結果會是這樣的代碼:

public static string Verify(string valueToBind, object dataSource) 
{ 
//what is the correct way to convert from object 
BaseDataSource baseInstance = dataSource as BaseDataSource; 

if baseInstance != null) 
{ 
    if (ListContainsValue(baseInstance.GetEntityList(), valueToBind)) return valueToBind; 
    CustomParameter p = baseInstance.Parameters["WhereClause"] as CustomParameter; 
    if (p != null) 
    { 
     p.Value = "IsActive=true OR Id=" + valueToBind; 
     baseInstance.Select(); 
     return valueToBind; 
    } 
} 

return string.Empty; 
} 

回答

2

如果您無法更改類定義或使用某種擴展方法,則可以使用反射。這裏是我的工作了使用你的代碼假設一個例子:

public static string Verify(string valueToBind, object dataSource) 
    { 
     ////what is the correct way to convert from object 
     //BaseDataSource baseInstance = dataSource as BaseDataSource; 
     Type type = dataSource.GetType(); 
     MethodInfo select = type.GetMethod("Select"); 
     PropertyInfo parameters = type.GetProperty("Parameters"); 
     PropertyInfo parameterGetter = null; 
     object parametersInstance = null; 
     if (parameters != null) 
     { 
      parametersInstance = parameters.GetValue(dataSource, null); 
      type = parametersInstance.GetType(); 
      parameterGetter = type.GetProperty("Item"); 
     } 

     //if baseInstance != null) 
     if (select != null && parameters != null && parameterGetter != null) 
     { 
       if (ListContainsValue(baseInstance.GetEntityList(), valueToBind)) return valueToBind; 
       CustomParameter p = parameterGetter.GetValue(parametersInstance, new object[] {"WhereClause" }) as CustomParameter; 

       if (p != null) 
       { 
         p.Value = "IsActive=true OR Id=" + valueToBind; 
         select.Invoke(dataSource, null); 
         return valueToBind; 
       } 
     } 

     return string.Empty; 
    } 
0

由於代碼不使用「現況」,這是很難討論實際問題......可以簡化該示例不依賴於外部庫/類?

我可以確認:是由NetTiers生成的DseDataSource?在這種情況下,NetTiers會生成「部分」類嗎?如果是這樣,你可以在第二類文件中添加接口的實現:

namespace YourNamespace { 
    partial class DseDataSource : IYourInterface { 
     // implement interface 
    } 
} 

這將功能添加到DseDataSource類,而無需您編輯生成的代碼。

+0

不,它不使用部分類,但是這是一個很好的方式來創建接口。我可以編輯NetTiers模板來使其部分或在那裏創建界面。但是我看到,如果這個演員能夠在那裏完成的話。 – CRice 2009-01-21 02:36:56

1

感謝約翰你真的把我在正確的道路上出現。 我結束了以下代碼:

public string Verify(string valueToBind, object dataSource) 
    { 
     IListDataSource listDataSource = dataSource as IListDataSource; 
     if (listDataSource != null) 
     { 
      if (ListContainsValue(listDataSource.GetEntityList(), valueToBind)) return valueToBind; 
     } 

     Type type = dataSource.GetType(); 
     MethodInfo select = type.GetMethod("Select", new Type[0]); 
     PropertyInfo parameterCollectionInfo = type.GetProperty("Parameters"); 
     ParameterCollection pc = parameterCollectionInfo.GetValue(dataSource, null) as ParameterCollection; 

     if (pc != null) 
     { 
      CustomParameter p = pc["WhereClause"] as CustomParameter; 
      if (p != null) 
      { 
       p.Value = "IsActive=true OR Id=" + valueToBind; 
       select.Invoke(dataSource, null); 
       return valueToBind; 
      } 
     } 

     return string.Empty; 
    }