Consider a class that maintains two private instances of Generic Lists, one
of type string, one of type int :
class PolyClass
{
private List<string> listOStrings;
private List<int> listOInts;
public polyClass
{
listOStrings = new List<string>();
listOInts = new List<int>;
}
}
Now you define an Add operator that takes a string and an int as its
parameters, and an overload for the Add operator that takes an int and a
string as its parameters. You add a Get operator that takes an int as its
input parameter and returns the string in the listOStrings List at the same
index location as the int in the listOInts. You create an over-ride for the
Get operator that takes a sting as input parameter and returns the matching
int.
So now someone can use your class to add items using either the string-frst,
or the int-first flavours of Add. And use the Get operator similarly. Yes,
all of this compiles and works fine.
My question is : does this type of coding in a way "violate" the strongly
typed "basis" of C#; i.e., is it a "bad" practice, a "tolerable" but unwise
practice, or ?
thanks, Bill
Peter Bromberg [C# MVP] - 27 Mar 2008 18:30 GMT
This is kind of like the thread some time ago about whether its advisable to
have a method that returns an instance of Exception as its return value.
Generally, most said it wasn't good form.
I think the real question is what do you hope to accomplish with this, and
given that, is there a more elegant / usable way to do it?
-- Peter
Site: http://www.eggheadcafe.com
UnBlog: http://petesbloggerama.blogspot.com
Short Urls & more: http://ittyurl.net
> Consider a class that maintains two private instances of Generic Lists, one
> of type string, one of type int :
[quoted text clipped - 29 lines]
> thanks, Bill
>
Ignacio Machin ( .NET/ C# MVP ) - 27 Mar 2008 19:01 GMT
> Consider a class that maintains two private instances of Generic Lists, one
> of type string, one of type int :
[quoted text clipped - 29 lines]
>
> thanks, Bill
Hi,
What happens if you put the same integer twice? with different strings
of course.
Anyway , I do not see how the described feature violate nothing in the
first place (except having two Add methods for no reason). Basically
you are implementing a collection of {int,string} that can be searched
by either component.
Peter Duniho - 27 Mar 2008 19:02 GMT
> [...]
> My question is : does this type of coding in a way "violate" the strongly
> typed "basis" of C#; i.e., is it a "bad" practice, a "tolerable" but
> unwise
> practice, or ?
I can't say that I'd call it "unwise" per se. That is, absent any other
information, it's difficult if not impossible to characterize any random
design as "wise" or "unwise", because some designs that would normally be
unwise turn out to have some leigitimate application in some specific
scenario.
That said, I do tend to agree with Peter B.'s response, that if more
information is provided about the ultimate goal, it's entirely possible
that there's a better design and/or implementation choice (your question
really seems to be about both, actually).
Finally, I have to admit that I had to make some inferences in order to
understand your question, because what you wrote doesn't necessarily
describe what's even possible in C#. Those inferences are:
-- when you write "Add operator" you actually mean the "+" operator
(there's no such thing as an "Add operator", literally speaking)
-- when you write "Get operator" you actually mean an indexer (i.e.
defining "int this[string]" and "string this[int]") (likewise, there's no
literal "Get operator")
-- when you write "create an over-ride", you actually meant "create an
overload" (an override happens if you inherit the class, an overload
happens if you provide a method with the same name but a different
signature)
If those inferences are correct, then I'd say that at the very least,
overloading the "+" operator for this purpose seems like a poor choice,
especially given the types you're dealing with. There's already a
well-defined result when you "add" a string and an int (the int is
converted to a string and you get a new string that's the concatenation of
the two).
If those inferences aren't correct, then that's a good example of why it's
important to be precise about how you state your question. :) In this
particular case, it seems to me that the clearest way to demonstrate what
you're talking about would have been to just post the code, rather than
trying to describe it in words.
Pete
Ben Voigt [C++ MVP] - 27 Mar 2008 22:30 GMT
> Consider a class that maintains two private instances of Generic
> Lists, one of type string, one of type int :
[quoted text clipped - 18 lines]
> create an over-ride for the Get operator that takes a sting as input
> parameter and returns the matching int.
Sounds like a "content-addressable buffer". I'd probably prefer different
names for the functions instead of overloading, but the concept is valid.
> thanks, Bill
Steve Gerrard - 28 Mar 2008 03:11 GMT
> So now someone can use your class to add items using either the
> string-frst, or the int-first flavours of Add. And use the Get
[quoted text clipped - 3 lines]
> strongly typed "basis" of C#; i.e., is it a "bad" practice, a
> "tolerable" but unwise practice, or ?
I don't see the point of having two versions of Add, if they both do the same
thing.
It seems strange to me to have an overloaded Get that returns different types.
Most overloads vary the parameters, but not the return type.
Bill Woodruff - 28 Mar 2008 13:27 GMT
Hi, First, my apologies for not posting a more detailed original post, and
for posting code that had at least two spelling errros (my main development
machine is now non-nettable and non net-workable for unknown reasons, so I
hand typed the code on my laptop).
Appended a complete version of a class that demonstrates multi-type setting
and getting ... I have made the two lists here type specific but you could
just as well make them generic. In actual practice I use a "generic factory
object" built with generics to "spit out' classes whose types I specify like
this, but I made the included example non-generic to keep the code shorter
and focus on what for me is the main issue : "code usability and
appropriateness."
Real world use : synchronizing selection in one object/control where you
can only access items by indexing through ordinal position with selection in
another object/control where you can index by string ? Simulating something
in the real world that has bi-directional lookup of two types of data ?
Obviously constrained by the fact that lists cannot have duplicate keys.
My goal in presenting this is to ask the question if this type of class is
consistent with C#'s strongly typed nature. My own feelings about this are
ambiguous : on the one hand I feel it's a useful technique (particularly
when done up as a generic factory object); on the other hand I feel, in
terms of code maintenance, and programming style, it might be better not to
make it easy to set and get without explicitly stating the parameter type.
In other words having separately named 'getValueByKey and 'getKeyByValue
calls. Yes, in real world use there would be type-checking and throwing of
ArgumentException errors, but I've left that out for code brevity.
And, yes, there's no reason you can't make a class like this inherit from
List<T> or whatever and take advantage of the default behavior of that type
which, in this case, would require you to only implement one internal List,
and to override the Add operator of List once, etc.
Hope this is a clearer post. best, Bill
using System;
using System.Collections.Generic;
using System.Text;
namespace testPolyFunction
{
class polyClass
{
private List<string> listOStrings;
private List<int> listOInts;
public polyClass()
{
listOStrings = new List<string>();
listOInts = new List<int>();
}
public void set(string theString, int theInt)
{
listOStrings.Add(theString);
listOInts.Add(theInt);
}
public void set(int theInt, string theString)
{
set(theString, theInt);
}
public int get(string theString)
{
return listOInts[listOStrings.IndexOf(theString)];
}
public string get(int theInt)
{
return listOStrings[listOInts.IndexOf(theInt)];
}
}
}