[英]Can you populate a derived class object using data acess methods that return base class objects?
我想創建一個實現一些新方法的繼承對象。 基類只是一個數據容器,並使用數據訪問類填充。
我試圖使用一個強制框架,所以更改這些基類的選擇非常有限。
由於繼承的對象具有與基礎相同的所有數據字段和訪問器,因此我想使用基礎的Data Access類(及其方法)來填充派生的類對象。 我的問題是DA層返回類型為Base的填充對象。
實際上,我正在嘗試復制字段。 我知道我可以創建一個接受基礎對象的構造函數,並有效地逐字段復制,但這是基礎表本質的維護噩夢。
有什么方法可以在不重新編碼DA層的情況下進行轉換嗎?
我相信唯一的方法就是創建一個派生的數據訪問類,該類將處理派生的基類,但是有更好的方法嗎?
偽代碼如下。 該示例看似微不足道,但DA層封裝了許多數據檢查和異常處理,因此在不破壞許多現有功能的情況下,很難以任何有意義的方式進行修改。
我希望這是有道理的,因為可能沒有放置很多代碼,所以可能沒有意義。
基類
public class oBase
{
#region "Constants"
public const String FIELD_META_ID = "META_ID";
public const String FIELD_MASTER_REF = "MASTER_REF";
#endregion
//Private Properties
private Int32 m_iMetaID = 0;
private String m_sMasterReference = "";
//End Private Properties
//Public Properties
public Int32 MetaID { get { return m_iMetaID; } set { m_iMetaID = value; } }
public String MasterReference { get { return m_sMasterReference; } set { m_sMasterReference = value; } }
//End Public Properties
}
public class oBaseList
{
private Int32 iMemberCount = 0;
private List<oBase> m_BaseList = new List<oBase>();
public Int32 Count
{
get { return m_BaseList.Count; }
}
public List<oBase> Items
{
get { return m_BaseList; }
}
public Boolean AddItem(oBase)
{
iMemberCount += 1;
m_BaseList.Add(oBase);
return true;
}
}
擴展類
class oBaseExtended : oBase
{
public oBaseExtended(int iMetaID)
{
ConnectionManagerSQL oSqlConn = new ConnectionManagerSQL();
daBase MyConnectedData = new daBase(ref oSqlConn);
oBase MyCastData = new oBaseExtended();
MyCastData = MyConnectedData.GetData(iMetaID);
oBaseExtended MyRealData = (oBaseExtended)MyCastData;
return MyRealData;
}
}
資料存取
public class daBase
{
private ConnectionManagerSQL oConn;
public daBase(ref ConnectionManagerSQL sqlConn)
{
oConn = sqlConn;
}
#region "Gets"
public oBase GetBase(Int32 iMetaID)
{
StringBuilder sb = new StringBuilder();
sb.Append(" SELECT ");
sb.Append(" META_ID, ");
sb.Append(" MASTER_REF, ");
sb.Append(" from myTable ");
sb.Append(" where META_ID = @META_ID");
SqlCommand comm = new SqlCommand(sb.ToString(), oConn.DatabaseConnection);
comm.Parameters.Add("META_ID", System.Data.SqlDbType.Int).Value = iMetaID;
SqlDataReader drMyTableData = comm.ExecuteReader();
return PopulateMyTableData(ref drMyTableData).Items[0];
}
#endregion
#region "List population "
private oBaseList PopulateMyTableData(ref SqlDataReader drMyTableData)
{
oBaseList ocdMyTableData = new oBaseList();
oBase ocd;
ocd = new oBase();
ocd.MetaID = drMyTableData[oBase.FIELD_META_ID] is System.DBNull ? 0 : (Int32)drMyTableData[oBase.FIELD_META_ID];
ocd.MasterReference = drMyTableData[oBase.FIELD_MASTER_REF] is System.DBNull ? "N/A" : (String)drMyTableData[oBase.FIELD_MASTER_REF];
ocdMyTableData.AddItem(ocd);
drMyTableData.Dispose();
return ocdMyTableData;
}
#endregion
}
抱歉,如果不清楚,是否有任何偽代碼錯誤-我是C#新手。
我已經更新了代碼以更好地反映真實的基礎代碼。
最好提出這樣的問題:我可以簡單地使用強制轉換並將其復制到繼承的類型...
您可以使用反射將同名的屬性和字段的值從一個對象復制到另一個對象。 檢查https://msdn.microsoft.com/zh-cn/library/system.type%28v=vs.110%29.aspx感興趣的方法是GetProperties
和GetFields
。 然后在PropertyInfo
和FieldInfo
,感興趣的方法是GetValue
和SetValue
。
您可以編寫一種復制屬性/字段的方法,並將其用於每個基對/派生對。 或任何其他對象對,只要屬性和同名字段都是可分配的(即,不能將字符串分配給int等)。
編輯:此方法復制屬性的值:
static void CopyData(object source, object destination)
{
Type srcType = source.GetType();
List<PropertyInfo> destProperties = new List<PropertyInfo>(destination.GetType().GetProperties());
foreach (PropertyInfo destProperty in destProperties)
{
if (destProperty.CanWrite)
{
PropertyInfo srcProperty = srcType.GetProperty(destProperty.Name);
if (srcProperty != null && srcProperty.CanRead)
{
destProperty.SetValue(destination, srcProperty.GetValue(source));
}
}
}
}
如果需要,也嘗試添加字段復制,這是相同的原理。
您可以通過基類構造函數填充派生類/基類共享的成員,也可以根據需要填充派生類中的所有擴展成員:
public class oBase
{
private Int32 m_i = 0;
private String m_s = "";
public Int32 MI { get { return m_i; } set { m_i = value; } }
public String MS { get { return m_s; } set { m_s = value; } }
public oBase() { }
public oBase(int i)
{
// populate base class members using instance of data access class
}
}
然后,您的派生類將擴展基本構造函數以填充任何擴展屬性(我不認為您有任何屬性?):
public class oBaseExtended : oBase
{
public string foo { get; set; }
public string bar { get; set; }
public oBaseExtended() { }
public oBaseExtended(int i) : base(i)
{
// this will invoke base class contructor to populate base members
// then populate extended members afterwards if applicable
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.