Creating new properties in a struct, outside of said struct
This is kind of hard to explain, so bear with me.
In PHP, if you wanted create a new property in a class, you could without doing anything. The following code would work perfectly.
class testClass
{
public function __construct()
{
}
}
$test = new testClass;
$test->propone = "abc";
echo $test->propone;
I would like to do the same thing, only in C# and wi开发者_StackOverflowth a struct. Is this possible?
Yes, I know, this sounds really clunky. I am trying to simulate a sort of associative array, where there is none. In my environment (NET Microframeworks), hashtables and dictionaries are not supported (yet).
Thanks!
Don't simulate an associative array - go write one and use it.
As far as I know there's no way to add properties dynamically at runtime. Nor is there a way to add properties at compile-time aside from adding them directly to the declaration. In my opinion, this is good as it maintains the type-safety expected from C#.
However, couldn't you make a primitive hashtable using List<KeyValuePair<int, List<KeyValuePair<string, object>>>>
and String.GetHashCode()
? Something like the following (untested and part-pseudocode, but you get the idea):
class HashTable<T>
{
private List<KeyValuePair<int, List<KeyValuePair<string, T>>>> _table =
new List<KeyValuePair<int, List<KeyValuePair<string, T>>>>();
private void Set(string key, T value)
{
var hashcode = key.GetHashCode();
List<KeyValuePair<string, T>> l;
if(!_table.TryGetValue(hashcode, out l))
{
l = new List<KeyValuePair<string, T>>();
_table.Add(hashcode, l);
}
T o;
if(l.TryGetValue(key, out o))
{
if (o != value)
l.Single(x => x.Key == key).Value = o;
}
else
l.Add(new KeyValuePair(key, value));
}
private T Get(string key)
{
List<KeyValuePair<string, T>> l;
object o;
if(!(_table.TryGetValue(hashcode, out l) &&
!l.TryGetValue(key, out o)))
{
throw new ArgumentOutOfRangeException("key");
}
return o;
}
}
The following should help you with TryGetValue
:
public bool TryGetValue<TKey, TValue>(this List<KeyValuePair<TKey, TValue>> list,
TKey key, out TValue value)
{
var query = list.Where(x => x.Key == key);
value = query.SingleOrDefault().Value;
return query.Any();
}
In C# version 4.0, as released with .NET 4.0 and Visual Studio 2010, the new pseudo type dynamic can allow you to do what you want - though if you're new to C# (as you seem to be) it's likely the techniques involved will be a bit deep.
All you need to do is to implement the appropriate interface; once this is done, any client code that uses your object dynamically may access on-the-fly properties (and methods) much like your PHP example.
References if you want to know more ...
- Using Type dynamic (C# Programming Guide)
- What's the difference between dynamic(C# 4) and var?
- Fun With Method Missing and C# 4
- Dynamic in C# 4.0: Introducing the ExpandoObject
精彩评论