How can I create -- CustomClass[propertyName].CustomMethod ?

G

Guest

I can't figure out how to approach this problem.
I would like to have a custom object that will contain some predefined
attributes.

The simple solution that I know is to create my own class -- something like:

public class MyClass
{
private string _property01 = string.Empty;

public string property01
{
get { return _property01; }
set { this._property01 = value; }
}
}

And use all hard-coded assignments like:

MyClass someRecord = new MyClass();
someRecord.Property01 = "blah blah";
string anotherBlah = someRecord.Property01;

What I am looking for is to generalize properties of my custom class as well
as generalize future population of those properties.

I think that I need a construct like this:
{
....
propertyName = "property01"

someRecord[propertyName].Value = "blah blah"
string anotherBlah = someRecord[propertyName].Value;
....
}
and perhaps extending that class with more methods like:

someRecord[propertyName].Remove;
someRecord[propertyName].Add;
someRecord[propertyName].Whatever;

It is seems to me that I will need to inherit from CollectionBase and use
some sort of constructor like:

public MyClass this[int index]
{
get { return ((MyClass)(List[index])); }
set { List[index] = value; }
}

Should I create some sort of a "special" constructor for my "MyClass" class?

With the one I've got I can return value by integer "index" which is a
sollectionBase IList method, I gathering... Which i could not make to work
anyway...

How can I supply my own "search" by name of the attribute, and not by its
index?
Should I extend constructor? Should I inherit from something else? Or
perhaps I am completely off-track with this idea.

Please advice.

Thanks in advance.
 
M

Marc Gravell

Well, in terms of implementation, you would be better of with a
hashtable. In 2.0, you could use

privatate readonly Dictionary<string, object> propertyBag = new
Dictionary<string, object>();

public object this[string propertyName] {
get {// returns null if not defined
object value;
propertyBag.TryGetValue(propertyName, out value);
return value;
}
set {
propertyBag[propertyName] = value;
}
}

However, this isn't type safe, doesn't (as is) support notifications,
and doesn't show in the component model (e.g. for use in tables).

Doing this /properly/ is not a trivial task, but can be done. Lots of
code, though, and you need a pretty good undertanding of the component
model. I would recommend keeping it simple (as above) unless you know
you need the extra functionality (e.g. for binding the virtual
properties directly to winforms in the standard way, or supporting a
complex diffgram model).

I have an architecture that does all this (broadly comparable to a
DataSet, but entirely "normal class" based), but it is much, much code.
I might post it somewhere when complete... but way too long for an
ng...

Marc
 
M

Marc Gravell

Note: to support methods on each, the item in the dictionary would be a
class with a property for the value; at the simplest (using fields for
brevity; use properties IRL):

public class PropertyBagValue {
public object Value;
public void Whatever() {}
}

I think the Remove and Add belong naturally to the parent; this
approach also allows you to start looking at change notifications (with
a reference to the parent), but not completely.

Search: depends how you want it to behave! Since we are talking about a
single instance (not a collection of instances) I'm not sure what you'd
want to search *on*, but if you did have e.g. a List<T> a predicate
would be trivial:

list.FindAll(delegate (MyClass item) {
return item["SomeProperty"] == 5; // using original code, not .Value
});

Finally - CollectionBase is wrong for the *outer* class here; it is a
single item, not a collection of those items. It can encapsulate a
collection of its properties (as a private implementation detail), but
that doesn't /make/ it a collection in the normal sense.

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top