Reputation: 11360
I have 2 entities, 'Deal' and 'Store'. I want to combine these in a single list, along with an integer or something else indicating the type.
I've done a bit of googling and come up with a solution, but as its all pretty new and confusing, I'm unsure as to whether its the best solution.
I've used an interface to do this - code below, and i'd appreciate some advice as to whether this is the correct and reasonable approach.
public interface IBookmarkWrapper
{
int DataType { get; private set; }
object Data { get; private set; }
}
public class DealBookmarkWrapper : IBookmarkWrapper
{
public int DataType { get; private set; }
public object Data { get; private set; }
public DealBookmarkWrapper(Deal deal)
{
deal.ThrowNull("deal");
DataType = 1;
Data = deal;
}
}
And in use:
var list = new List<IBookmarkWrapper>();
list.Add(new DealBookmarkWrapper(deal));
Upvotes: 1
Views: 7030
Reputation: 1732
Have you thought about using a C# Struct?
struct DealBookmarker
{
public Deal Dl;
public Store St;
public int Type;
}
List<DealBookmarker> DBM = new List<DealBookmarker>();
DBM.add(new DealBookmarker)
you can also add a constructor to the Struct if necessary
unlike classes which are ref types structs are value types which allows you to create objects that act like built in data types also since it is initiated on the stack instead of the heap it will yield performance gains.
Benefits of using struct over a class in this case:
Upvotes: 1
Reputation: 12231
If you're going to use it in a repeater (i hope you actually mean ListView), then just define your properties in the interface and then implement the interface in the Deal and Store classes. Then you can just bind the List to the repeater/listview and call the properties by name. No need for any trickery. By doing this, the interface is guaranteeing that your properties are available (otherwise DataTextvalue will break during binding).
In other words, if you're gonna bind to a ListView, display properties need to be named the same in both the Store and Deal classes. So you might as well use the interface in its most basic form:
protected Page_Load(object sender, EventArgs e)
{
var list = new List<IWatchamacallit>();
list.Add(new Store { Property1 = "Store1", Property2 = "StoreInfo"});
list.Add(new Store { Property1 = "Store2", Property2 = "StoreInfo" });
list.Add(new Deal { Property1 = "Deal1", Property2 = "DealInfo" });
list.Add(new Deal { Property1 = "Deal2", Property2 = "DealInfo" });
myListView.DataSource = list;
myListView.DataBind();
/* from here just set your page controls to call the properties
for instance:
<asp:Label Text='<%# Eval("Property1") %>' />
<asp:Label text='<%# Eval("Property2") %>' />
*/
}
public interface IWatchamacallit
{
string Property1 { get; set; }
string Property2 { get; set; }
}
public class Store : IWatchamacallit
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
public class Deal : IWatchamacallit
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
Your input would bind up looking something like:
Property1 Property1
=====================
Deal1 DealInfo
Deal2 DealInfo
Store1 StoreInfo
Store2 StoreInfo
Any other values that you need to hold onto (like dealId or storeId) can be added as properties to your classes. Just make sure you define them in the interface and use consistent naming. By doing this, you can fill a list with two different types while maintaining your class structures. If you need to pick them out of the list later, you can just cast out like this:
foreach (var item in list)
{
var tempContainer = Activator.CreateInstance(item.GetType());
tempContainer = item;
}
Or any of several other ways, depending on what you're trying to accomplish.
Upvotes: 1
Reputation: 29000
You can implement Factory method
(Pattern of GOF)
Link : http://www.dofactory.com/Patterns/PatternFactory.aspx
Nota :
'Deal' and 'Store' are your Concrete Product
IBookmarkWrapper is your Product
And define Creator
Upvotes: 1