I am making some validation functions for my project but I am stuck on something.
I want to have a single function to handle a couple of different controls and errors.
Here's my code:
private void ValidateControls(Control c)
{
if (c is TextBox)
{
if (c.Text == "")
{
epNew.SetError(c, "Something");
}
}
else if (c is ComboBox)
{
// What now?
// if (c.SelectedItem == null) does not work
}
}
And I am calling it like this:
private void txtNEAN_Validating(object sender, CancelEventArgs e)
{
ValidateControls(txtNEAN);
}
This works fine for textboxes. But if I do:
private void cbbEMerk_Validating(object sender, CancelEventArgs e)
{
ValidateControls(cbbEMerk);
}
if (c.SelectedItem == null) for example does not work.
How can I achieve this? And is this okay to use? If not, what is a better alternative?
I'd love to hear anything!
You have to cast c to a ComboBox in this case
else if (c is ComboBox)
{
if (((ComboBox)c).SelectedItem == null)
}
By the way, don't create a _Validating method for every control if they do the same thing. You can use a single one, or one txtBox_Validating for TextBoxes, one comboBox_Validating for comboboxes, etc.
Try using
((ComboBox)c).SelectedItem
instead. This tells the program to parse the Control c into a ComboBox.
As an alternative, instead of using is you could use as
// Converts c to a ComboBox. If c is not a ComboBox, assigns null to cmbControl
ComboBox cmbControl = c as ComboBox;
if (cmbControl != null)
{
if (cmbControl.SelectedItem != null)
{
// Do stuff here
}
}
// Else it's not a ComboBox
It is also good to know about safety cast using as and is:
Because objects are polymorphic, it is possible for a variable of a base class type to hold a derived type. To access the derived type's method, it is necessary to cast the value back to the derived type. However, to attempt a simple cast in these cases creates the risk of throwing an InvalidCastException. That is why C# provides the is and as operators. You can use these operators to test whether a cast will succeed without causing an exception to be thrown. In general, the as operator is more efficient because it actually returns the cast value if the cast can be made successfully. The is operator returns only a Boolean value. It can therefore be used when you just want to determine an object's type but do not have to actually cast it.
You can see more here
Related
I'm trying to make a function that returns the actual control. I know you can do this when you know the type of the object:
public static Control GetCtl(this object obj)
{
//(obj as obj.GetType()) ?
return (TextBox)obj;
}
But what if I need to get one from some other (unknown) object type, for example TextBox or RichTextBox? I will then use that on:
private void TextBox1_Click(object sender, EventArgs e)
{
sender.GetCtl().Select(0, 0);
}
Though TextBox and RichTextBox seem to have the same Select method, when I tried the above GetCtl() function, it always threw an error. How do I do this properly?
Edit:
Since you cannot access the "complete" control property as sender in all native procedures/methods (i.e _Click(), _MouseMove()) I want to make a function that can return the actual control, not sure how to explain this better, but here's how I would use it:
Private void SomeControl_KeyDown(object sender, KeyEventArgs e){
sender.getCtl(). //<-- so I can access anything here
(sender as Button).Text = "sometext" // <-- so I won't have to do this
//I wish the following would work. But you get the idea
(sender.GetType())sender.Text = "";
//or...
(sender as sender.GetType()).Text = "";
}
RichTextBox and TextBox are both derived from TextBoxBase.
To tell the compiler that you want to treat an object as a specific type, you can perform a cast operation. In this case, you need to cast sender to TextBoxBase and then you can access the Select() method:
private void TextBox1_Click(object sender, EventArgs e)
{
var textbox = sender as TextBoxBase;
if (textbox != null)
textbox.Select(0, 0);
}
This uses the as keyword to cast the sender object to TextBoxBase. Note that you can't simply cast anything to anything else. The object being cast must actually be an instance of the type you're casting to. If sender is not an instance of something derived from TextBoxBase, the cast operation will return null.
Generally winforms event handlers should only be raised in very controlled and known circumstances - you should be very confident that this event is being raised by a control derived from TextBoxBase. There's not much point in raising it from anything else.
If you really want a method to convert sender to a TextBoxBase, you could write it as:
private TextBoxBase ToTextBoxBase(object sender)
{
var textbox = sender as TextBoxBase;
if (textbox == null)
throw new Exception("The given object is not derived from TextBoxBase");
return textbox;
}
You would use it like:
ToTextBoxBase(sender).Select(0, 0);
If the sender is not a TextBoxBase, this call would throw the "The given object is not derived from TextBoxBase" exception.
The important point to understand is that you are working with a strongly typed language. If you attempt to call a method of an object which is not of a type containing that method, the program won't even compile (unless the type is dynamic, but that's another discussion).
It is possible to create a method that you can call with this syntax:
sender.ToTextBoxBase()
This is called an extension method. However, you would be extending the System.Object class for a very specific purpose, which is not recommended.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
It is important to me that my syntax does not make other developers confused.
In this example, I need to know if a parameter is a certain type.
I have hit this before; what's the most elegant, clear approach to test "not is"?
Method 1:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if (!(e.parameter is MyClass)) { /* do something */ }
}
Method 2:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if (e.parameter is MyClass) { } else { /* do something */ }
}
Method 3:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
var _Parameter = e.parameter as MyClass;
if (_Parameter != null) { /* do something */ }
}
Method 4:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
var _Type = typeof(MyClass);
switch (e.parameter.GetType())
{
case _Type: /* do nothing */; break;
default: /* do something */; break;
}
}
[EDIT] Method 5:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if ((e.parameter is MyClass) == false) { /* do something */ }
}
Which is the most straight-forward approach?
This is obviously a matter of personal opinion and style, so there's no right answer, but I think this is clearest:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if ((e.parameter is MyClass) == false) { /* do something */ }
}
The == false is just more obvious than the !
I would go for 3 if you need the variable later or 1 if you don't need the variable.
2 is ugly because of the empty block.
However I think they all are straight-forward.
I would think just making an extension method would be a clear way of doing it:
public static bool CannotBeCastAs<T>(this object actual)
where T: class
{
return (actual as T == null);
}
You then simply make a check like so:
if(myObject.CannotBeCastAs<SomeClass>())
{
}
Methods 1 and 3 would be my picks, depending on what I actually wanted.
Method 1 "does something" if and only if the passed object is not of the expected type. This means the passed object could be null and still pass.
Method 3 "does something" if the passed object is not of the expected type, OR if the object is null. This is basically a one-pass check that you have a "valid" instance of the class to work with further.
So, whether I wanted 1 or 3 depends on what I was planning to do. Usually, when the variable isn't of the expected type or is null, I want to throw an exception. If I were happy with throwing just one type of exception (say just an ArgumentException), I'd use method 3. If I wanted to check for null separately and throw an ArgumentNullException, I'd use method 1 and add the null check.
Method 2 is functionally correct, but I'd rather invert the if condition as in Method 1, as an if block that does nothing is redundant.
I would never do Method 4. A switch statement taking the place of a simple if-else is unnecessary and confusing, especially in the manner you're using it.
To me, Method 1 is the most straight-forward, both on its own and by convention. This is the syntax I've seen the most if you just need to know if an object "is-a" certain class.
If you actually need to do something with the object "as-a" certain class, then Method 3 is the way to go.
Method 1 is the best in my view. It's very obvious what the code is doing and I can follow right along. Method 2 introduces unnecessary syntax that is easily corrected by Method 1. Method 3 requires me to think more than the other two (marginally, but still!), and it also uses extra space that isn't needed.
Remember code is written for people to read, and only after for machines to execute. Go with clarity every time.
If you want elegance and readability:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
bool isMyClass = e.parameter is MyClass;
if (!isMyClass) // or isMyClass == false
{
/* do something */
}
}
I've always tried my best not to put too much logic in a single line of code, specially if conditions. I think the type check and negation operator might be annoying to parse on first glance.
Method #5 (a different spin)
public static class TypeExtensions
{
public static bool IsNotTypeOf<T, X>(this T instance, X typeInstance)
{
return instance.GetType() != typeInstance.GetType();
}
}
// ...
if(e.parameter.IsNotTypeOf(MyClass)) { /* do something */ } ;
I would be of the opinion that braced functionality should always match whatever brace pattern is in use in your application. For instance, in the case of iteration or conditional blocks, if you use:
If (foo != bar)
{
//Do Something
}
well then this should be how you use brace patterned functionality at all times. One of my biggest bugbears with reading other peoples code (and this is especially true if they use CodeRush or Resharper) is the unnecessary terseness people add for no other reason than to display wizardry.
I am not saying the above is the best brace matching pattern however, use whatever one you feel comfortable with, what I would like to get across is that the pattern does not matter so much as the consistency of its use.
Personally, since C# is a terse language in comparison to, say VB.Net I would use long form statements or assignments (with the exception of var initialising) over more condense syntax to help aid later readability.
I like an approach used by one of the NUnit Assert's:
Assert.InstanceOf<MyType>(objectInstance);
BTW,
If you have a set of checks whether object is of specific type like:
if(objectInstance is TypeA)
{
// ...
}else
{
if(objectInstance is TypeC)
{
// ...
}
}
There should be some design issues like tied coupling between few types, so consider an other approach like injected map of associations or map like algorithm method per type
IDictionary<Type, Func<TParameter>>
In C#, I am building custom controls to be used in a custom application. I want each control to implement an event that will fire if an exception or error (an internal check failure) occurs inside the controls. I created an interface that declares the event. I create user controls that implement the interface. Here's my problem.
When I add one of my custom controls to a form, I want to loop through the controls on the form, detect all controls that are my custom controls and then assign an event handler to the event I declare in the interface. I cannot find a way to cast an object to the type of the interface.
Consider:
interface IMyInterface
{
event ControlExceptionOccured ControlExceptionOccuredEvent;
...
}
public partial class TextControl : UserControl, IMyInterface {
...
public event ControlExceptionOccured ControlExceptionOccuredEvent;
...
}
and on my form I use one of these TextControls. I have this method:
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control Control in Controls)
{
if (Control.GetType().GetInterface(typeof(IMyInterface).FullName) != null)
{
((IMyInterface)Control).ControlExceptionOccuredEvent += ControlExceptionHandler;
}
}
}
This complies but will not execute. How can I add ControlExceptionHandler to the event chain?
My thanks to anyone who tries to help.
As much as I understand yuo're not able to subscribe to the event cause IF condition returns FALSE. Did yuo try to write something like this ? :
foreach(Control ctrl in this.Controls){
if((ctrl as IMyInterface) != null) {
//do stuff
}
}
This is a simpler way to do it:
if (control is IMyInterface)
((IMyInterface)control).ControlExceptionOccuredEvent += ControlExceptionHandler;
... But the way you're doing it should work too, so you'll have to provide more details about what's happening.
The code
((IMyInterface)Control).ControlExceptionOccuredEvent += ControlExceptionHandler;
generates
Unable to cast object of type '...Text.TextControl' to type 'IMyInterface'.
I do not understand why not.
As a side note, I replaced
if (Control.GetType().GetInterface(typeof(IMyInterface).FullName) != null)
with
if (Control is IMyInterface)
and it does not work. The second example never returns true. I also tried
if ((Control as IMyInterface) != null)
and it also never returns true.
I have a function that takes a control as parameter, and depending on the control's type (e.g.: TextBox, ComboBox, RadioButton etc...), it executes type-specific code:
internal static void DoSomething(Control control)
{
if (control is Button)
{
// code for button
}
else if (control is CheckBox)
{
// code for CheckBox
}
else if (control is TextBox)
{
// code for TextBox
}
// etc.....
}
I am wondering if this is the best way to do.
I know of some other ways to do the same thing (e.g.: looking for the control's type using GetType(), switching on the string representation of this type), and Microsoft's code analysis tool tells me to use 'as' instead of 'is' like this (because it is better performance-wise):
internal static void DoSomething(Control control)
{
Button button = control as Button
if (button != null)
{
// code for button
}
else
{
CheckBox checkBox = control as CheckBox;
if (checkBox != null)
{
// code for CheckBox
}
else
{
TextBox textBox = control as TextBox;
if (textBox != null)
{
// code for TextBox
}
// etc.....
}
}
}
but I find this last solution rather wordy and not very practical to read.
I'd like to be able to switch on the control's type directly, but am unable do to so without resorting to use the string representation (which I don't like at all) as a switch's case statement cannot contain a variable.
So what really is the best way to do performance-wise? and what is, in you opinion, the best way to do? (not necessarily performance-wise, but "code-readability-wise" for instance)
Edit: as a lot is going on on the subject of "why do I use one common function and not many type-specific methods", here is some more info:
I get a control variable from an other part of the app I'm working on (type = Control) and I have do "do something" with this variable, depending on its type.
so basically, I have the choice between 2 options: either I use one common function and check the control's type in the function's body so that I execute the right portion of the code at some point (options I have chosen for now, but this could change), or I check for the control's type BEFORE calling a type-specific method.
either way, I have to switch on the control's type at some point, and THIS is the subject of my question (regardless of what I do with it, if I may say so).
I would use Dictionary for it and (also separate methods for each handler):
private static readonly Dictionary<Type, Action<Control>> _handlers
= new Dictionary<Type, Action<Control>>();
// Handle.. methods
private static void HandleButton(Button button) { ... }
private static void HandleListbox(Listbox listbox) { ... }
private static void RegisterHandler<T>(Action<T> handler)
where T: Control
{
_handlers.Add(typeof(T), o => handler((T)o));
}
// invoke this method in static constructor
private static void InitializeHandlers()
{
RegisterHandler<Button>(HandleButton);
RegisterHandler<Listbox>(HandleListbox);
}
// finally usage:
internal static void DoSomething(Control control)
{
var handler = _handlers[control.GetType()];
handler(control);
}
The benefit for this approach is some maintainability improvement:
1. You will know that you haven't registered several handlers for same parameter type (dictionary will throw an exception)
2. You will have all your handler registrations separately which will allow you easily finding out which method handles particular parameter type.
3. Since all handler locating logic is not repeated at all it is pretty easy to modify it in order to handle inhereting types for example (my code doesn't do this but your code did)
Well, you don't need to nest on the second one use else if.
Second why are you putting all of this into one method? It would be better since at the time that you are calling this you should know what the type of the control that it is calling this method is and from there just Do the DoSomething for that control type instead of all of this conditional checking.
I think you're fine using the "is" operator here. It's more readable, and you don't really have any useful alternate path in the case that the control isn't what you were looking for anyway. I don't believe the timing differences will be that critical in this case.
You could swap out the "else if"s for a series of plain "if"s by returning from each individual if block, but that's a personal style choice.
It would be better to refactor the generic (control-agnostic) functionality into a separate function, and have the control-specific functionality in control-specific functions.
You can then call the generic function from the control-specific function where appropriate.
This is the kind of solution I would opt for:
internal class MyClass
{
private const string ButtonTypeAsString = "Button";
private const string CheckBoxTypeAsString = "CheckBox";
private const string TextBoxTypeAsString = "TextBox";
private static string GetTypeAsString(Control control)
{
string result = String.empty;
if (result.Length == 0 && (control as Button) != null)
{
result = MyClass.ButtonTypeAsString;
}
if (result.Length == 0 && (control as CheckBox) != null)
{
result = MyClass.CheckBoxTypeAsString;
}
if (result.Length == 0 && (control as TextBox) != null)
{
result = MyClass.TextBoxTypeAsString;
}
if (result.Length == 0)
{
throw new InvalidOperationException("Control type is not handled by this method.");
}
return result;
}
internal static void DoSomething(Control control)
{
string controlTypeAsString = MyClass.GetTypeAsString(control);
switch (controlTypeAsString)
{
case MyClass.ButtonTypeAsString:
// Button stuff
break;
case MyClass.CheckBoxTypeAsString:
// Checkbox stuff
break;
case MyClass.TextBoxTypeAsString:
// TextBox stuff
break;
default:
throw new InvalidOperationException("Unexpected Control type");
}
}
}
... but I'm sure some would find this overkill. Personally, I like the readability of the switch statement and try to use it whenever possible. Also, avoiding switching on "Magic Strings." Use const strings when possible.
If you don't mind me asking, what is it exactly you're trying to do? There may be a better solution that doesn't involve having to infer a Control's type.
if I have a delegate like so:
Delegate void Render();
Render ToRender;
And use it here:
ToRender += FunctionRender;
ToRender += SomeOtherRender;
How can I make it so I can invoke each function seperately? Something like this:
foreach(Render render in ToRender)
{
BeginRender();
render();
EndRender();
}
You can fetch each one separately using Delegate.GetInvocationList().
foreach (Render render in ToRender.GetInvocationList())
{
...
}
Note that GetInvocationList() just returns a Delegate[], but foreach has an implicit cast on each item, which is what makes the above loop work.
Oh, and you should check whether ToRender is null or not first, of course - otherwise you'll get a NullReferenceException. You could actually write a generic extension method to make this nicer, but you'd need a constraint on the delegate type which isn't allowed in C# :(
If you don't care about the lack of constraints, you could fake it:
public static IEnumerable<T> GetIndividualDelegates<T>(this T multiDelegate)
where T : class
{
if (multiDelegate == null)
{
yield break;
}
Delegate d = (Delegate)(object) multiDelegate;
foreach (Delegate item in d.GetInvocationList())
{
yield return (T)(object) item;
}
}
(It's awkward because of the restrictions on generic conversions.)
That way you could write:
foreach (Render render in ToRender.GetIndividualDelegates())
{
...
}
without worrying about whether ToRender was null or not.
foreach (Render render in ToRender.GetInvocationList())
Ideal Way:
Render temp = ToRender;
if (temp != null)
{
foreach (Render render in temp.GetInvocationList())
{
BeginRender();
render();
EndRender();
}
}
ToRender.GetInvocationList returns an array of all delegates contained on the "list".
thats not how delegates and events work. all methods will automatically be invoked by the framework. event handlers should be able to be executed completely independent of any other handlers. if you need to control the flow more tightly, you should think about redesigning your approach.
perhaps 3 events/delegates - similar to the way asp.net does it. PreRender, Render and PostRender. im not sure what you are doing, but this sounds like overkill to me. just thought i would throw it out.