|
Nasty! If you are letting your engineers make "simple changes to the screens" you do realise they will need full VS to do it? Which means they could do anything to your screens. Including f@ck them up completely...
If these guys are not bright enough to be trusted with default names and the ability to change them, then why are you going to trust them not to make a complete pigs-ear of the whole system?
Did you know:
That by counting the rings on a tree trunk, you can tell how many other trees it has slept with.
|
|
|
|
|
hmmm i have to agree with you every time a promting for the name would suck
actually you need to write an addin for the IDE (VS oder #Develop).
The addin should override the INameCreationService of the DesignerHost.
then you can create a name the "normal" way or prompt for it
sooo far
|
|
|
|
|
alright i have the solution worked out!!
but you need to wait till i am at home i will write an article about your problem because this is very interesing stuff
so please be patient..
greetz all over the world
|
|
|
|
|
ok
Thanks in advance
Chris
Chris
|
|
|
|
|
|
Ok so you may have seen my very basic question yesterday and I'm back today to build the project up and could use some pointers on virtual and abstract and how to apply them.
In a nutshell my project has a FruitBase class that simply establishes private fields and then public properties that each individual fruit will have.
public class FruitBase
{
private string _name;
private string _colour;
public FruitBase()
{
}
public virtual string Name
{
get { return _name; }
set { _name = value; }
}
public string Colour
{
get { return _colour; }
set { _colour = value; }
}
}
I then have individual fruit classes eg. apple, banana etc. that set the default values within thier constructors, eg.
public class Apple: FruitBase
{
public Apple()
{
this.Name = "Apple";
this.Colour = "Red";
}
}
The idea is the user selects a radio button for a fruit type and we then return the defaults on a button press, which runs the function GetValues().
<asp:RadioButtonList runat="server" ID="radList" RepeatDirection="Horizontal">
<asp:ListItem Text="Apple" Value="Apple" />
<asp:ListItem Text="Banana" Value="Banana" />
<asp:ListItem Text="Orange" Value="Orange" />
<asp:ListItem Text="Pear" Value="Pear" />
</asp:RadioButtonList>
<asp:Button runat="server" ID="btnFruit" Text="Get" OnClick="GetValues" />
<br />
<br />
<asp:TextBox runat="server" ID="txtOuput" TextMode="MultiLine" Width="250px" />
The issue is I am trying to avoid is a long-winded, repetative piece of code such as
public void GetValues(object sender, EventArgs e)
{
string Ftype = FruitBase.GetType();
if(Ftype = Apple)
{
}
else if(Ftype = Banana)
{
}
else.........
}
As you can imagine if I include every type of fruit in a supermarket as an option I'll quickly end up with hundreds of lines of code.
So, to my (admittedly basic) knowledge, I should be able to create a virtual method within the FruitBase class that takes an object of FruitBase as a parameter and will then retrieve the default values of the users chosen fruit without any explicit mention of the chosen class (Basically avoiding any long if statements).
Immediately I'm stuck however.
First of all, how do I use the radio buttons selectedValue to specify the chosen fruit class, without another if(value = "Apple") else.....
Secondly how do I then pass this as an object and have the virtual method retrieve the default values from the correct class without being explicit and again avoiding the if..else situation mentioned above.
I realise this is a little long winded and I'm not great with the correct terminology but this was an example technical test at a recent job interview and I didn't get it so now I want to get my head round it.
Thanks for reading and any help is greatly appreciated
|
|
|
|
|
The best suited solution is to use Factory Pattern[^].
It is very easy to manage situation using Factory Pattern.
HTH
Jinal Desai - LIVE
Experience is mother of sage....
|
|
|
|
|
Hi Jinal, to an extent yes this is what I'm attempting to do.
However within the wikipedia articles c# example there is this block of code;
public static IPizza CreatePizza(PizzaType pizzaType)
{
switch (pizzaType)
{
case PizzaType.HamMushroom:
return new HamAndMushroomPizza();
case PizzaType.Deluxe:
return new DeluxePizza();
case PizzaType.Hawaiian:
return new HawaiianPizza();
default:
throw new ArgumentException("The pizza type " + pizzaType + " is not recognized.");
}
}
So I still have the problem of a long winded repetitive case statement or if statement.
From what i have read if a base fruit method or property is marked virtual, and you call said method or property on some unknown fruit, C# will see which kind of fruit you really have a hold of and call ITS designated overridden version. Thus avoiding ifs and case statements but how do I get to that point?
|
|
|
|
|
I got it. There is one alternative solution.
In factory pattern you need to implement one more layer.
That is your BasePizza class, from which every type of
pizza derived.
In BasePizza you can define methods and properties as
virtual.
So for creating the object of pizza will look like following.
public static IPizza CreatePizza(PizzaType pizzaType)
{
switch (pizzaType)
{
case PizzaType.HamMushroom:
return new HamAndMushroomPizza();
case PizzaType.Deluxe:
return new DeluxePizza();
case PizzaType.Hawaiian:
return new HawaiianPizza();
default:
return new BasePizza();
}
}
The other pizza type like HamAndMushroomPizza, DeluxePizza, etc are derived
from BasePizza.
HTH
Jinal Desai - LIVE
Experience is mother of sage....
|
|
|
|
|
If you really don't want to write ifs for each new fruit you add, you can use reflection like this:
<br />
Assembly assembly = typeof(FruitBase).Assembly;<br />
Type type = assembly.GetType(name);<br />
object obj = Activator.CreateInstance(type);<br />
This code assumes that all fruit classes are defined in the same assembly as FruitBase. After this code is executed obj contains fruit selected.
You should of course add some error checking, try-catches, but the basic idea remains.
Don't forget to rate answer, that helped you. It will allow other people find their answers faster.
|
|
|
|
|
Could you possibly clarify this please Lukasz?
Where does this block of code go exactly?
Why does the type always return null, regardless of which string I pass into the assembly.GetType(name)?
|
|
|
|
|
Ok so I'm at the point now where my class file looks like this;
public class FruitBase
{
private string _name;
private string _colour;
public FruitBase()
{
}
public virtual string Name
{
get { return _name; }
set { _name = value; }
}
public string Colour
{
get { return _colour; }
set { _colour = value; }
}
public virtual void GetDefaults(FruitBase fruit)
{
fruit.GetDefaults(fruit);
}
}
public class Apple: FruitBase
{
public Apple()
{
}
public override void GetDefaults(FruitBase fruit)
{
this.Name = "Apple";
this.Colour = "Red";
}
}
and my button click event runs this
FruitBase fb = new FruitBase();
FruitBase fb2 = new FruitBase();
if (radList.SelectedValue == "Apple")
{
fb2 = new Apple();
}
else if (radList.SelectedValue == "Banana")
{
fb2 = new Banana();
}
else if (radList.SelectedValue == "Orange")
{
fb2 = new Orange();
}
else if (radList.SelectedValue == "Pear")
{
fb2 = new Pear();
}
fb.GetDefaults(fb2);
txtOuput.Text = fb.Name + " - " + fb.Colour + "/" + fb2.Name + " - " + fb2.Colour;
Now this works as the fb2.Name and colour return the correct values for the fruit type BUT a huge part of this was for me to eradicate the if statement you can see above in the click event.
So now my question is hHow do I use the radList.SelectedValue to pass the chosen FruitBase object without the if statement?
|
|
|
|
|
Instead of your ifs you should put code:
<br />
Assembly assembly = typeof(FruitBase).Assembly;<br />
Type type = assembly.GetType(name);<br />
object obj = Activator.CreateInstance(type);<br />
FruitBase fb2 = obj as FruitBase;<br />
It should work.
Oh. I forgot, that the assembly.GetType(name) expects fully qualified type name (class name with namespace: YourNamespace.Banana or something like this). I hope all fruits are in the same namespace. If they are, then instead of
Type type = assembly.GetType(name);
write
Type type = assembly.GetType(string.Format("{0}.{1}", "YourNamespace", name);
If they aren't, then move them to a single namespace
Don't forget to rate answer, that helped you. It will allow other people find their answers faster.
|
|
|
|
|
Lukasz, my man! That works a treat, exactly what I was looking for! I can't thank you enough for that, I really appreciate you taking the time to help and now I will look more into Assembly and System.Reflection in more detail.
For anyone interested here is the final code that works.
Class file;
namespace FruitBase_EG
{
public class FruitBase
{
private string _name;
private string _colour;
public FruitBase()
{
}
public virtual string Name
{
get { return _name; }
set { _name = value; }
}
public string Colour
{
get { return _colour; }
set { _colour = value; }
}
public virtual void GetDefaults()
{
this.Name = "Fruit";
this.Colour = "White";
}
}
public class Apple: FruitBase
{
public Apple()
{
}
public override void GetDefaults()
{
this.Name = "Apple";
this.Colour = "Red";
}
}
public class Banana : FruitBase
{
public Banana()
{
}
public override void GetDefaults()
{
this.Name = "Banana";
this.Colour = "Yellow";
}
}
}
And my code behind looks like this;
namespace FruitBase_EG
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void GetValues(object sender, EventArgs e)
{
string name = radList.SelectedValue;
Assembly assembly = typeof(FruitBase).Assembly;
Type type = assembly.GetType(string.Format("{0}.{1}","FruitBase_EG", name));
object obj = Activator.CreateInstance(type);
FruitBase fb = obj as FruitBase;
fb.GetDefaults();
txtOuput.Text = fb.Name + " - " + fb.Colour;
}
}
}
Now when the user selects a fruit using the radio button, on the click event of the Get Details button we run through the code above and it picks up the users choice and then sets the FruitBase class to which ever individual fruit class we have chosen, eventually outputting the name and colour values to the textbox
|
|
|
|
|
One more thing. The code for creating selected fruit I mean
<br />
Assembly assembly = typeof(FruitBase).Assembly;<br />
Type type = assembly.GetType(string.Format("{0}.{1}","FruitBase_EG", name));<br />
object obj = Activator.CreateInstance(type);<br />
FruitBase fb = obj as FruitBase;<br />
should be placed int try-catch block, because it uses user input, and user input isn't supposed to be trusted
And another thing: you can move setting defaults to constructor (change your fruits' classes to
public class FruitBase
{
private string _name;
private string _colour;
public FruitBase()
{
this.Name = "Fruit";
this.Colour = "White";
}
public virtual string Name
{
get { return _name; }
set { _name = value; }
}
public string Colour
{
get { return _colour; }
set { _colour = value; }
}
}
public class Apple: FruitBase
{
public Apple()
{
this.Name = "Apple";
this.Colour = "Red";
}
}
public class Banana : FruitBase
{
public Banana()
{
this.Name = "Banana";
this.Colour = "Yellow";
}
}
And now, if you remove the call fb.GetDefaults(); it should still work. And it will be more user friendly
Don't forget to rate answer, that helped you. It will allow other people find their answers faster.
|
|
|
|
|
Personally, I would never do that unless the contents of the assembly in question are unknown at compile time. The performance of code like this just blows. Even if I had to do this, I would fill a dictionary with strings as keys and factory objects/delegates as values instead of using reflection all the time.
But each to their own.
|
|
|
|
|
Personally, I would caution against using reflection. It is poor practice when you own the code.
Now to get down to the Nitty gritty, will your fruit objects perform custom actions based on the object type? It is possible that you have one of the cases for less classes and not more. The pattern below works well when you have a database of objects that really only differ Categorically as far as you are concerned. Technically it can be considered a Domain. You see it a lot when loading lists from databases for drop downs. I included the enumerator and the static Get method for use in populating and retrieving from combo boxes however there are an infinite number of ways to do it.
Since this is for an interview, this method is nice in that it circumvents many of the expected problems and gotchas with a lot less code.
public class Fruit {
private static Dictionary<string, Fruit> mFruits = new Dictionary<string, Fruit>();
private string mName;
private string mColor;
public static Fruit GetFruit(string name){
return mFruits[name];
}
public static IEnumerator<Fruit> GetFruits() {
return mFruits.Values.GetEnumerator();
}
public string Name {
get {
return mName;
}
private set {
mName = value;
}
}
public string Color {
get {
return mColor;
}
private set {
mColor = value;
}
}
private Fruit(string name, string color) {
Name = name;
Color = color;
}
static Fruit() {
mFruits.Add("Apple", new Fruit("Apple", "Red"));
mFruits.Add("Banana", new Fruit("Banana", "Yellow"));
}
}
|
|
|
|
|
Is there a single function that takes 2 string[] arrays and concatenates them together in a single string[] array?
string[] s1 = { "one", "two" };
string[] s2 = { "three", "four" };
string[] s = { "one", "two", "three", "four" };
Чесноков
|
|
|
|
|
Use CopyTo[^].
"If you think it's expensive to hire a professional to do the job, wait until you hire an amateur." Red Adair.
nils illegitimus carborundum
me, me, me
|
|
|
|
|
<br />
System.Collections.Generic.List<string> lst = new System.Collections.Generic.List<string>();<br />
lst.AddRange(s1);<br />
lst.AddRange(s2);<br />
string[] s = new string[lst.Count];<br />
lst.CopyTo(s);<br />
lst.Clear();<br />
lst = null;<br />
|
|
|
|
|
simple table management
string[] s = new string[s1.Length + s2.Length];
int _sCounter = 0;
for(int i=0;i<s1.Length;i++)
s[_sCounter++] = s1[i];
for(int i=0;i<s2.Length;i++)
s[_sCounter++] = s2[i];
|
|
|
|
|
Chesnokov Yuriy wrote: Is there a single function that takes 2 string[] arrays and concatenates them together in a single string[] array?
I think following function will do the stuff, right?
public static string[] ConcateArray(string[] s1, string[] s2)
{
string[] s = new string[s1.Length + s2.Length];
s1.CopyTo(s, 0);
s2.CopyTo(s, s1.Length);
return s;
}
Just call the method as
string[] s = ConcateArray(s1, s2);
Knock out 't' from can't, you can if you think you can.
|
|
|
|
|
|
|
Hi,
I am trying to read a 32-bit bitmap file and save it another place as 24-bit,
i tried this code but the saved bitmap i get is 32-bit
ImageCodecInfo _codedInfo = GetEncoderInfo("image/bmp");
System.Drawing.Imaging.Encoder _encoder = System.Drawing.Imaging.Encoder.ColorDepth;
EncoderParameters _encoderParameters = new EncoderParameters(1);
EncoderParameter _encoderParameter = new EncoderParameter(_encoder, 24L);
_encoderParameters.Param[0] = _encoderParameter;
System.Drawing.Bitmap _bitmap = new System.Drawing.Bitmap(_filename);
_bitmap = new System.Drawing.Bitmap(_bitmap.GetThumbnailImage(16, 16, myCallback, IntPtr.Zero));
_bitmap.Save(_newFileName,_codedInfo, _encoderParameters);
Please HELP, Regards
|
|
|
|