473,216 Members | 2,214 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,216 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 1267
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 cant use generics... Im 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
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

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.