471,338 Members | 1,488 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,338 software developers and data experts.

Is it possible to access properties of Generic types?

I have a Class "Multidictionary" which I created which is basically a
dictionary which can have multiple values for the same key. The class centers
around
private Dictionary<K, List<V>_InnerDictionary;
and provides methods to add to the InnerDictionary, remove from the
InnerDictionary and so forth.
I would like to have methods which allow me to retrieve or renmove single
value items based on a specific value of one pf their properties. I can't
figure out how to be able to examine the values of properties of a geneic
type. I suspect that it is possible with Reflection, but I can't find.
What I am thinking of is something like:

public void RemoveItemsWithSpecificValuePropertyValue(P
comparisonValue)
{
foreach (K key in _InnerDictionary)
{
foreach (V value in K)
{
if (value.P == comparisonValue)//This is the part that I
don't know how to do
{
// Remove value from list
}
}
}
}

Thanks for any help!
Ethan

Jun 27 '08 #1
7 3729
On Jun 13, 11:28*am, Ethan Strauss
<EthanStra...@discussions.microsoft.comwrote:
I have a Class "Multidictionary" which I created which is basically a
dictionary which can have multiple values for the same key. The class centers
around
* * * * private Dictionary<K, List<V>_InnerDictionary;
Yep, that is how it;s done

one qeustion though, where is your class defined ???
In the code above you are simply using the Dictionary class provided
by the framework

Of course you can do it with reflection, the fact that It's "generic"
has nothing to do., if you have something like

note that this code was written in the google's editor, not tested or
compiled

class MyDir<TKey, TValue>: Dictionary<Tkey, TValue>{

public object FindByProperty( TKey key, string pName ){
//decide if TValue is enumerable or no
if ( this[TKey] is IEnumerable )
{
foreach(object o in (IEnumerable) this[TKey] )
if ( HasValue( o, pName ) )
return o;
}
else
return HasValue ( this[TKey], pName ) ? this[TKey]: null;
}

HasValue( object o, string propertyName )
{
// use reflection to get the value
}

}
and provides methods to add to the InnerDictionary, remove from the
InnerDictionary and so forth.
* * * * I would like to have methods which allow me to retrieve orrenmove single
value items based on a specific value of one pf their properties. I can't
figure out how to be able to examine the values of properties of a geneic
type. I suspect that it is possible with Reflection, but I can't find.

What I am thinking of is something like:

* * * * public void RemoveItemsWithSpecificValuePropertyValue(P
comparisonValue)
* * * * {
* * * * * * foreach (K key in _InnerDictionary)
* * * * * * {
* * * * * * * * foreach (V value in K)
* * * * * * * * {
* * * * * * * * * * if (value.P == comparisonValue)//This is the part that I
don't know how to do
* * * * * * * * * * {
* * * * * * * * * * * * // * * *Remove valuefrom list
* * * * * * * * * * }
* * * * * * * * }
* * * * * * }
* * * * }

Thanks for any help!
Ethan
Jun 27 '08 #2
Thanks!
Can you expand on your "HasValue" method? I have never used reflection I
can't figure that bit out. I think I can handle the rest once I get that.
Ethan

"Ignacio Machin ( .NET/ C# MVP )" wrote:
On Jun 13, 11:28 am, Ethan Strauss
<EthanStra...@discussions.microsoft.comwrote:
I have a Class "Multidictionary" which I created which is basically a
dictionary which can have multiple values for the same key. The class centers
around
private Dictionary<K, List<V>_InnerDictionary;

Yep, that is how it;s done

one qeustion though, where is your class defined ???
In the code above you are simply using the Dictionary class provided
by the framework
I didn't show most of the code for the class. The rest is constructors and
methods to interact with that dictionary.
>
Of course you can do it with reflection, the fact that It's "generic"
has nothing to do., if you have something like

note that this code was written in the google's editor, not tested or
compiled

class MyDir<TKey, TValue>: Dictionary<Tkey, TValue>{

public object FindByProperty( TKey key, string pName ){
//decide if TValue is enumerable or no
if ( this[TKey] is IEnumerable )
{
foreach(object o in (IEnumerable) this[TKey] )
if ( HasValue( o, pName ) )
return o;
}
else
return HasValue ( this[TKey], pName ) ? this[TKey]: null;
}

HasValue( object o, string propertyName )
{
// use reflection to get the value
}

}
and provides methods to add to the InnerDictionary, remove from the
InnerDictionary and so forth.
I would like to have methods which allow me to retrieve or renmove single
value items based on a specific value of one pf their properties. I can't
figure out how to be able to examine the values of properties of a geneic
type. I suspect that it is possible with Reflection, but I can't find.

What I am thinking of is something like:

public void RemoveItemsWithSpecificValuePropertyValue(P
comparisonValue)
{
foreach (K key in _InnerDictionary)
{
foreach (V value in K)
{
if (value.P == comparisonValue)//This is the part that I
don't know how to do
{
// Remove value from list
}
}
}
}

Thanks for any help!
Ethan

Jun 27 '08 #3
>foreach (K key in _InnerDictionary) {
foreach (V value in K) {
if (value.P == comparisonValue) {
// This is the part that I don't know how to do
// Remove value from list
}
}
}
I don't think you can do this. What you would want is to call the
"value.Remove()" method, but this would cause problems in your itteration.

Instead, look into something like this *untested* code:

for (int i = 0; i < _InnerDictionary.Count; i++) {
for (int j = 0; j < K.Count; j++) {
if (K[j].P == comparisonValue) {
K[j].Remove();
// or
_InnerDictionary.Item[i].Remove();
}
}
}
Jun 27 '08 #4
On Jun 13, 11:28 am, Ethan Strauss
<EthanStra...@discussions.microsoft.comwrote:
I have a Class "Multidictionary" which I created which is basically a
dictionary which can have multiple values for the same key. The class centers
around
private Dictionary<K, List<V>_InnerDictionary;
and provides methods to add to the InnerDictionary, remove from the
InnerDictionary and so forth.
I would like to have methods which allow me to retrieve or renmove single
value items based on a specific value of one pf their properties. I can't
figure out how to be able to examine the values of properties of a geneic
type. I suspect that it is possible with Reflection, but I can't find.

What I am thinking of is something like:

public void RemoveItemsWithSpecificValuePropertyValue(P
comparisonValue)
{
foreach (K key in _InnerDictionary)
{
foreach (V value in K)
{
if (value.P == comparisonValue)//This is the part that I
don't know how to do
{
// Remove value from list
}
}
}
}

Thanks for any help!
Ethan
What i think you are looking for is a constraint.
where V : (Some class which is a base class for your Vs or an
interface implemnted by V which has the property P)
Jun 27 '08 #5
You might be better-off with a "predicate" approach... this would let
the caller decide what are useful conditions to remove items, and
ensures type-safety while removing the need for reflection - for
example see below.

[example uses C# 3; if you don't have VS2008 let me know - the
approach is fine for C# 2 and .NET 2.0]

Marc

using System;
using System.Collections.Generic;
class Foo
{
public string Bar { get; set; }
public int Whatever { get; set; }
}
static class Program
{
static void Main()
{
var dict = new MultiDictionary<string, Foo>();
dict.Add("abc", new Foo { Bar = "item 1", Whatever = 4 });
dict.Add("def", new Foo { Bar = "item 2", Whatever = 4 });
dict.Add("abc", new Foo { Bar = "item 3", Whatever = 3 });
dict.Add("abc", new Foo { Bar = "item 4", Whatever = 9 });
dict.Add("ghi", new Foo { Bar = "item 5", Whatever = 4 });
int removed = dict.RemoveAll(foo =foo.Whatever == 4);
}
}
class MultiDictionary<TKey, TValue>
{
public void Add(TKey key, TValue value)
{
List<TValueitems;
if (!list.TryGetValue(key, out items))
{
items = new List<TValue>();
list.Add(key, items);
}
items.Add(value);
}
public int RemoveAll(Predicate<TValuematch)
{
List<TKeykillKeys = new List<TKey>();
int count = 0;
// remove all matching items, noting any sub-lists
// that are now empty
foreach (var pair in list)
{
count += pair.Value.RemoveAll(match);
if (pair.Value.Count == 0) killKeys.Add(pair.Key);
}
// remove the empty sub-lists
foreach (TKey killKey in killKeys)
{
list.Remove(killKey);
}
return count;
}
private Dictionary<TKey, List<TValue>list;

public MultiDictionary() : this(null) { }
public MultiDictionary(IEqualityComparer<TKeycomparer)
{
list = new Dictionary<TKey, List<TValue>>(
comparer ?? EqualityComparer<TKey>.Default);
}
}
Jun 27 '08 #6
Thanks Marc,
This approach looks very promising. I am using VS2005 (.Net 2.0), but I
think you have given enough direction to get me where I want to go.
Ethan

"Marc Gravell" wrote:
You might be better-off with a "predicate" approach... this would let
the caller decide what are useful conditions to remove items, and
ensures type-safety while removing the need for reflection - for
example see below.

[example uses C# 3; if you don't have VS2008 let me know - the
approach is fine for C# 2 and .NET 2.0]

Marc

using System;
using System.Collections.Generic;
class Foo
{
public string Bar { get; set; }
public int Whatever { get; set; }
}
static class Program
{
static void Main()
{
var dict = new MultiDictionary<string, Foo>();
dict.Add("abc", new Foo { Bar = "item 1", Whatever = 4 });
dict.Add("def", new Foo { Bar = "item 2", Whatever = 4 });
dict.Add("abc", new Foo { Bar = "item 3", Whatever = 3 });
dict.Add("abc", new Foo { Bar = "item 4", Whatever = 9 });
dict.Add("ghi", new Foo { Bar = "item 5", Whatever = 4 });
int removed = dict.RemoveAll(foo =foo.Whatever == 4);
}
}
class MultiDictionary<TKey, TValue>
{
public void Add(TKey key, TValue value)
{
List<TValueitems;
if (!list.TryGetValue(key, out items))
{
items = new List<TValue>();
list.Add(key, items);
}
items.Add(value);
}
public int RemoveAll(Predicate<TValuematch)
{
List<TKeykillKeys = new List<TKey>();
int count = 0;
// remove all matching items, noting any sub-lists
// that are now empty
foreach (var pair in list)
{
count += pair.Value.RemoveAll(match);
if (pair.Value.Count == 0) killKeys.Add(pair.Key);
}
// remove the empty sub-lists
foreach (TKey killKey in killKeys)
{
list.Remove(killKey);
}
return count;
}
private Dictionary<TKey, List<TValue>list;

public MultiDictionary() : this(null) { }
public MultiDictionary(IEqualityComparer<TKeycomparer)
{
list = new Dictionary<TKey, List<TValue>>(
comparer ?? EqualityComparer<TKey>.Default);
}
}
Jun 27 '08 #7
I should add that there is an "EditableLookup<TKey,TValue>" that I
wrote, in Jon Skeet's "MiscUtil" and acts in a similar manner.
http://www.pobox.com/~skeet/csharp/miscutil

This maps to the .NET 3.5 ILookup<TKey,TValueinterface (and the
immutable Lookup<TKey,TValueclass), but IIRC it also compiles
in .NET 2.0 [we tried to get as much as possible to play nicely
with .NET 2.0]; I don't think it has a RemoveAll(predicate) method at
the moment, but it might make a useful starting point.

Marc
Jun 27 '08 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Justin Shen | last post: by
4 posts views Thread by Andrew Ducker | last post: by
4 posts views Thread by =?Utf-8?B?c2lwcHl1Y29ubg==?= | last post: by
reply views Thread by =?Utf-8?B?RnV0cm9uaWNzIERldmVsb3Blcg==?= | last post: by
26 posts views Thread by raylopez99 | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.