473,378 Members | 1,314 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Can this be done via .net generics? How?

Can this be done via .net generics? How? The % signs below are just to show
how I want to do it, I realise they're not valid syntax.

public abstract class BaseSelectionRequirement {
...
protected Type mControlType;
protected string mFieldName;
protected Type mFieldType;
protected UserControl mControl;
...

public %mFieldType% Value {
get {
return ( ( %mControlType% ) mControl ).%mFieldName%;
}
set {
( ( %mControlType% ) mControl ).%mFieldName% = value;
}
}
}

So, say my descended class was:

public class HatSelectionRequirement : BaseSelectionRequirement {
public HatSelectionRequirement( ) {
mControlType = HatUserControl;
mFieldType = typeof( Int32 );
mFieldName = "Size";
}
...
}

Then I could get/set the int HatUserControl.Size via
HatSelectionRequirement.Value
Jul 23 '07 #1
7 1273
Andy Bell wrote:
Can this be done via .net generics? How? The % signs below are just
to show how I want to do it, I realise they're not valid syntax.

public abstract class BaseSelectionRequirement {
...
protected Type mControlType;
protected string mFieldName;
protected Type mFieldType;
protected UserControl mControl;
...

public %mFieldType% Value {
get {
return ( ( %mControlType% ) mControl ).%mFieldName%;
}
set {
( ( %mControlType% ) mControl ).%mFieldName% = value;
}
}
}

So, say my descended class was:

public class HatSelectionRequirement : BaseSelectionRequirement {
public HatSelectionRequirement( ) {
mControlType = HatUserControl;
mFieldType = typeof( Int32 );
mFieldName = "Size";
}
...
}

Then I could get/set the int HatUserControl.Size via
HatSelectionRequirement.Value
THat's not the area where generics should be used. Generics should be
used to generalize a piece of algoritmic code by making the containing
class generic. THings like the fieldname aren't producable in generics,
generics is solely about types.

First of all, I'd like to recommend to you to NOT use protected fields
for members. Use private fields and protected properties. This allows
you to obtain the encapsulation that's often needed.

There's another problem with the design: there's a hard reference to
the control the object works on. This is odd to me, wouldn't it be
better to have a class which can work with any object of a given
control type?

I was half-way rewriting your abstract-nonabstract class tandem with a
property descriptor approach when it became really awkward, because:
where is the control instance passed in? If you want to read a value
from a live control, you have to pass it in. In your code that's not
done anywhere so I don't know how you want to do that.

The context of your code is also not very clear, so a good anwser is
abit hard to give.

FB
--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Jul 23 '07 #2
Hi Andy,

I suggest you define the BaseSelectionRequirement class as a generic class.
As for the implementation of the Value property, we don't know either the
field name or its type until at run time. So we need to use reflection to
get/set the field's value at run time.

The following is a sample.

public class BaseClass<mControlType,mFieldType>
{
protected string mFieldName;
protected UserControl mControl;

public mFieldType Value
{
get
{
PropertyDescriptor pd =
TypeDescriptor.GetProperties(mControl)[mFieldName];
if (pd != null)
{
return (mFieldType)pd.GetValue(mControl);
}
else
{
return default(mFieldType);
}

}
set
{
PropertyDescriptor pd =
TypeDescriptor.GetProperties(mControl)[mFieldName];
if (pd != null)
{
pd.SetValue(mControl, value);
}
}
}
}
public class DerivedClass:BaseClass<UserControl,Int32>
{
private UserControl uc = new UserControl();
public DerivedClass()
{
this.mFieldName = "Height";
this.mControl = uc;
}

}

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 23 '07 #3
Linda Liu [MSFT] wrote:
Hi Andy,

I suggest you define the BaseSelectionRequirement class as a generic
class. As for the implementation of the Value property, we don't know
either the field name or its type until at run time. So we need to
use reflection to get/set the field's value at run time.
That is exactly what I needed. It was the PropertyDescriptor that was
eluding me. Thank you!
Jul 24 '07 #4

"Andy Bell" <an************@newsgroup.nospamwrote in message
news:OE**************@TK2MSFTNGP03.phx.gbl...
Linda Liu [MSFT] wrote:
>Hi Andy,

I suggest you define the BaseSelectionRequirement class as a generic
class. As for the implementation of the Value property, we don't know
either the field name or its type until at run time. So we need to
use reflection to get/set the field's value at run time.

That is exactly what I needed. It was the PropertyDescriptor that was
eluding me. Thank you!
You should get a big performance improvement by defining "open" delegate
types:

mFieldType PropertyGetter<mControlType>(mControlType that);
void PropertySetter<mControlType>(mControlType that, mFieldType value);

and instantiating them using Delegate.CreateDelegate the results of
PropertyInfo.GetGetMethod and PropertyInfo.GetSetMethod, respectively, the
first time they are needed. Reflection is slow, if you can manage to avoid
using Invoke then you'll only pay the reflection cost the first time, when
you set up the delegates.

Highly recommended to define methods like:

class MissingAccessors<T{
static T PropertyNotGettable(object that) { throw new
NotSupportedException(); }
static void PropertyNotSettable(object that, T value) { throw new
NotSupportedException(); }
}

and use these to fill in your delegate members if reflection fails.
Jul 24 '07 #5
Hi Ben,

Thank you very much for your sharing!

I'm interested in your solution, but I couldn't understand it fully.

If possible, could you please give us a complete sample code?

Thank you for your time!

Sincerely,
Linda Liu
Microsoft Online Community Support

Jul 26 '07 #6

"Linda Liu [MSFT]" <v-****@online.microsoft.comwrote in message
news:MU**************@TK2MSFTNGHUB02.phx.gbl...
Hi Ben,

Thank you very much for your sharing!

I'm interested in your solution, but I couldn't understand it fully.

If possible, could you please give us a complete sample code?

Thank you for your time!
Something like this (not compile tested, but at least 99% there):

internal class MissingAccessors<T{
static T PropertyNotGettable(object that) { throw new
NotSupportedException(); }
static void PropertyNotSettable(object that, T value) { throw new
NotSupportedException(); }
}

public class ArbitraryPropertyProxy<mControlType, mFieldType>
{
public delegate mFieldType PropertyGetter(mControlType that);
public delegate void PropertySetter(mControlType that, mFieldType
value);

public readonly PropertyGetter getFrom;
public readonly PropertySetter setOnto;

public ArbitraryPropertyProxy(PropertyInfo pi)
{
if (pi.PropertyType != mFieldType) throw new ArgumentException();
try {
getFrom =
(PropertyGetter)Delegate.CreateDelegate(typeof(Pro pertyGetter),
pi.GetGetMethod());
}
catch {
getFrom = MissingAccessors<mFieldType>.PropertyNotGettable;
}
try {
setOnto =
(PropertySetter)Delegate.CreateDelegate(typeof(Pro pertySetter),
pi.GetSetMethod());
}
catch {
getFrom = MissingAccessors<mFieldType>.PropertyNotSettable;
}
}
}

public class PropertyLateBinder<mControlType, mFieldType>
{
private readonly static Dictionary<string,
ArbitraryPropertyProxy<mControlType, mFieldType>cachedProps = new
Dictionary<string, ArbitraryPropertyProxy<mControlType, mFieldType>>();

public static ArbitraryPropertyProxy<mControlType, mFieldType>
BindProperty(string propName)
{
ArbitraryPropertyProxy<mControlType, mFieldTypeproxy;
if (!cachedProps.TryGetValue(propName, out proxy)) {
try {
PropertyInfo pi =
typeof(mControlType).GetProperty(propName);
if (pi != null)
proxy = new ArbitraryPropertyProxy<mControlType,
mFieldType>(pi);
}
catch {}
cachedProps[propName] = proxy;
}
return proxy;
}

public static mFieldType Get(mControlType instance, string propName) {
ArbitraryPropertyProxy<mControlType, mFieldTypeproxy =
BindProperty(propName);
if (proxy == null) throw new ArgumentException("propName");
return proxy.getFrom(instance);
}

public static void Set(mControlType instance, string propName,
mFieldType newValue) {
ArbitraryPropertyProxy<mControlType, mFieldTypeproxy =
BindProperty(propName);
if (proxy == null) throw new ArgumentException("propName");
proxy.setOnto(instance, value);
}
}

void ChangeColor(Form f, Color c, string whichColor) {
foreach (Control c in f.Controls)
PropertyLateBinder<Control, Color>.Set(c, whichColor, c);
}

ChangeColor(this, Color.Black, "BackColor");
ChangeColor(this, Color.Red, "ForeColor");

Imagine that whichColor could be a dropdown list or something like that, so
it's not feasible to do early binding.
Aug 2 '07 #7
Hello Ben,

Thank you very much for your great code!

It will definitly improve the performance. And I think it benefit all of us.

Thank you again for your support of our MSDN managed Newsgroup!

Sincerely,
Linda Liu
Microsoft Online Community Support

Aug 6 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

27
by: Bernardo Heynemann | last post by:
How can I use Generics? How can I use C# 2.0? I already have VS.NET 2003 Enterprise Edition and still can´t use generics... I´m trying to make a generic collection myCollection<vartype> and...
2
by: Mr.Tickle | last post by:
So whats the deal here regarding Generics in the 2004 release and templates currently in C++?
23
by: Luc Vaillant | last post by:
I need to initialise a typed parameter depending of its type in a generic class. I have tried to use the C++ template form as follow, but it doesn't work. It seems to be a limitation of generics...
12
by: Michael S | last post by:
Why do people spend so much time writing complex generic types? for fun? to learn? for use? I think of generics like I do about operator overloading. Great to have as a language-feature, as...
5
by: anders.forsgren | last post by:
This is a common problem with generics, but I hope someone has found the best way of solving it. I have these classes: "Fruit" which is a baseclass, and "Apple" which is derived. Further I have...
11
by: herpers | last post by:
Hello, I probably don't see the obvious, but maybe you can help me out of this mess. The following is my problem: I created two classes NormDistribution and DiscDistribution. Both classes...
9
by: sloan | last post by:
I'm not the sharpest knife in the drawer, but not a dummy either. I'm looking for a good book which goes over Generics in great detail. and to have as a reference book on my shelf. Personal...
1
by: Vladimir Shiryaev | last post by:
Hello! Exception handling in generics seems to be a bit inconsistent to me. Imagine, I have "MyOwnException" class derived from "ApplicationException". I also have two classes...
13
by: rkausch | last post by:
Hello everyone, I'm writing because I'm frustrated with the implementation of C#'s generics, and need a workaround. I come from a Java background, and am currently writing a portion of an...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.