Can I identify the sub class from a base class parameter? - c#

Take a look at the following. The question near the end of the code - in the "whoAmI" function...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MY_TEST_PROJECT
{
// a form class
public partial class frmTestForm1 : Form
{
// zillion lines of code
private void aFunction()
{
ClassTest.whoAmI(this);
}
// zillion lines of code
}
// another form class...
public partial class frmTestForm2 : Form
{
// zillion lines of code
private void aFunction()
{
ClassTest.whoAmI(this);
}
// zillion lines of code
}
// a home made test class
public static class ClassTest
{
// zillion lines of code
public static void whoAmI(Form theForm)
{
// IS THERE A WAY TO SEE WHAT KIND OF FORM theForm IS?
// LIKE:
// if (theForm IS A frmTestForm1)
// doThis();
// else if (theForm IS A frmTestForm2)
// doThat();
}
// zillion lines of code
}
}

You can check with the keyword is.
Also, you might want to solve your problem using polymorphism instead of checking the type.

There are few ways you can do this:
as you have guessed you can use "is" key word as Sjoerd has proposed
if (theForm is frmTestForm1)
doThis();
//So on
Another approach is to use reflection to get the exact type of the form you have. Your code should look like somthing like this:
if (theForm.GetType().UnderlyingSystemType
== typeof(frmTestForm1))
doThis();
The drawback of the first approach is that if, for example, your frmTestForm2 is derivative of frmTestForm1 and you use code like this if(yourform is frmTestForm1) and your form is pointing to a frmTestForm2 instance "is" keyword will return true.

Did you try this and it is not working? There is no problem trying to get a type from an object. Although you are sending it in as the base type the object still is a derived class type.

if (theForm.GetType().ToString() == typeof(frmTestForm1).ToString())
{
// Do your stuff
}

Related

C# error while calling class

I learned basic and now I want to learn OOP in C#
I have this code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace uceni_cs
{
class Zdravic
{
public void pozdrav()
{
Console.WriteLine("Ahoj světe ! ");
}
}
}
But when I try to call it using this code
namespace uceni_cs
{
class Zdravic
{
public void pozdrav()
{
Console.WriteLine("Ahoj světe ! ");
}
}
Zdravic trida = new Zdravic();
}
In code Zdravic trida = new Zdravic();
is error. A namespace cannot directly contain members such as fields or methods.
What I am doing wrong ? I just want to call the class.
Thanks
In C# there is no such a thing global variable so you can't just create new instance of Zdravic type that does not belong to any class.
I suggest you to read General Structure of a C# Program, and c# Classes and Structs.
You need to create an entry point to your application and instantiate the class there.
class EntryPoint
{
static void Main()
{
Zdravic trida = new Zdravic();
trida.pozdrav();
}
}
Create your class object in main method and then use the class properties using that object.
Zdravic trida = new Zdravic();
in main method of you program/application.

How to use IEnumerable<T> in a class constructor parameter

I am trying to make some code in my MVC controller (export to Excel) more generic, as I've reached the point where I'm typing out almost identical code in multiple controllers. To make the export to Excel function so that exists in only one place -- rather than in many places -- I had the idea of using a generic IEnumerable so I could feed any IEnumerable into the class. (See code block below.)
I know that I can use byte[] as a parameter (and I might still use that as an other constructor choice), but it would be nice if I could use an IEnumerable in this instance.
However, Intellisense immediately tells me that "the type or namespace T could not be found".
Is is possible to use IEnumerable<T> for this purpose?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebApplication1.CentralFunctions
{
public class ExportToExcel
{
ExportToExcel(IEnumerable<T> inputCollection)
{
// TODO: place my "export to excel" commands here.
}
}
}
You need to define what T represents to the compiler somewhere. Since you are dealing with a class constructor, you need to make the class generic in order to define T.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebApplication1.CentralFunctions
{
public class ExportToExcel<T>
{
ExportToExcel(IEnumerable<T> inputCollection)
{
// TODO: place my "export to excel" commands here.
}
}
}
The T type is «unknown», i.e. not specified.
It seems you want to make the ExportToExcel class generic, and the T seems to be a type parameter:
public class ExportToExcel<T>
{
ExportToExcel(IEnumerable<T> inputCollection)
{
// ...
}
}
You need to declare your T type at class level, If you want you can also add a constraint to T
public class ExportToExcel<T>
{
ExportToExcel(IEnumerable<T> inputCollection)
{
// TODO: place my "export to excel" commands here.
}
}
I have accepted #NightOwl888 as the best answer. Thank you to #Sergei and #Luke for also answering.
Their answers helped me to write the class constructor correctly and now I can greatly simplify my code. I am sharing this because it explains the full context of the question and demonstrates how I can place it into my MVC system. This is the "hello world" version and can serve to help others like me who are figuring out how to get started.
Now I can simplify the controller action to this:
View:
<p>#Html.ActionLink("Export to Excel","ExportToExcel")</p>
Controller Action:
public ActionResult ExportToExcel()
{
IEnumerable<TroveLog> data = db.TroveLogs.AsEnumerable();
var export = new ExportToExcel<TroveLog>(data);
return RedirectToAction("Index");
}
And this is where I can place the single block of code that can export any IEnumerable to Excel. When I use Debug mode (F5), I can see the Debug.WriteLine results and verify that I am seeing the correct information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
namespace WebApplication1.CentralFunctions
{
public class ExportToExcel<T>
{
private IEnumerable<T> data;
public ExportToExcel(IEnumerable<T> inputCollection)
{
this.data = inputCollection;
// Run in Debug Mode (F5) and see results when clicking ActionLink.
Debug.WriteLine("Object: {0}", data.GetType());
Debug.WriteLine("RowCount: {0}", data.Count());
// TODO: place my "export to excel" commands here.
}
}
}

Extension Methods with Custom Classes

I'm attempting to extend my custom classes and running into a problem where it cannot find the extension method.. I have and can extend any built in classes or even ones contained within DLL's. I don't know if this is a compilation error or if I'm doing something wrong. Threw together a small program for an example, won't compile..
Here's the extension:
namespace ExtensionMethodTesting.Extension
{
public static class Extension
{
public static void DoSomething(this ExtensionMethodTesting.Blah.CustomClass r)
{
}
}
}
Here's the Custom Class:
namespace ExtensionMethodTesting.Blah
{
public class CustomClass
{
public static void DoNothing()
{
}
}
}
Here's the code calling it:
using ExtensionMethodTesting.Blah;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExtensionMethodTesting.Extension;
namespace ExtensionMethodTesting
{
class Program
{
static void Main(string[] args)
{
CustomClass.DoNothing();
CustomClass.DoSomething();
}
}
}
I must be missing something... Anyways the exact error just for clarification is:
Error 1 'ExtensionMethodTesting.Blah.CustomClass' does not contain a definition for 'DoSomething' c:\users\damon\documents\visual studio 2013\Projects\ExtensionMethodTesting\ExtensionMethodTesting\Program.cs 16 25 ExtensionMethodTesting
Extension methods require an instance of an object. You'll have to new up a CustomClass to use it.
var custom = new CustomClass();
custom.DoSomething();
See this answer as to why that is.
You need to instantiate an object of the CustomClass to use its extension method.
CustomClass obj = new CustomClass();
obj.DoSomething();

Class structure confirmation

I have this class file call SMSHelper.cs First I just wanted to know is my written structure is Correct or Wrong?(My class file name is also SMSHelper.cs & my first class also SMSHelper here you can see in the code.).
Basically I have 3 classes in same file. One class has the same name as the file name.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Text.RegularExpressions;
namespace SMSBase.SMSFunction
{
public class SMSHelper : DotNetNuke.Entities.Modules.PortalModuleBase
{
// Some Code here
// Return Something here
}
public class Validator
{
public bool IsValidate(string Item)
{
// Some Code Here Not return anything
}
public class HuntingDate
{
//Implementation & Constructor here.. Return Something
}
}
}
There is nothing wrong in your class structure (except one missing bracket). And there is no matter your class name and file name are same. You can access and initialize your class objects like that...
SMSBase.SMSFunction.SMSHelper objSMSHelper = new SMSBase.SMSFunction.SMSHelper();
SMSBase.SMSFunction.Validator objValidator = new SMSBase.SMSFunction.Validator();
SMSBase.SMSFunction.HuntingDate objHuntingDate = new SMSBase.SMSFunction.HuntingDate();
This SMSBase.SMSFunction is your namespace... you can access classes by your namespace or include this namespace in the class header like
using SMSBase.SMSFunction
There is a problem in opening closing brackets:
namespace SMSBase.SMSFunction
{
public class SMSHelper : DotNetNuke.Entities.Modules.PortalModuleBase
{ // Some Code here // Return Something here
}
public class Validator
{
public bool IsValidate(string Item)
{ // Some Code Here Not return anything
}
}
public class HuntingDate
{ //Implementation & Constructor here.. Return Something
}
}
If that is what you are asking.
Yes as Talha ,said one bracket is missing.Try to put that.
When we want to call the class name its better to call with "namespace.ClassName" format which gives clarity to the compiler.

How do I add common C# code to a Visual C# 2008 Express project/solution?

(I still feel like a complete newbie in MS Visual environments... so please bear with!)
I'm using Microsoft Visual C# 2008 Express Edition.
I have a project and in that project are two different forms. The .cs file for each form starts out:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MyNameSpace
{
public partial class MyFormName : Form
{
...
(...and the second is "MyFormName2" but no differences besides that)
I want to write a function that I know both forms are going to need to access. I right-clicked on my project, selected "Add", selected "New Item" then selected "Code File" and named my file "Common.cs" and it gave me a completely blank file that's in my project.
How do I set this up...? I thought I should do the following...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MyNameSpace
{
}
...but then when I try to add a function like:
public void mytestfunc() {
}
within that namespace I get the following error:
"Expected class, delegate, enum, interface, or struct"
How do I set things up so I can have "mytestfunc" be available to both MyFormName and MyFormName2?
Thanks!
-Adeena
UPDATE:
Understand (now) that everything must be in a class, but then I don't understand how to really use it. Does that mean I have to create an object? This common function happens to just be some math...
so now if I have this:
namespace MyNameSpace
{
public class MyCommonClass
{
public void testFunc()
{
MessageBox.Show("Hee hee!");
return;
}
}
}
...how do I call testFunc from my Form? Must I do the following:
MyCommonClass temp = new MyCommonClass;
temp.testFunc();
or is there another way to call testFunc?
If you do something like:
namespace MyNameSpace
{
public class myclass
{
public myMethod()
{
// Code
}
}
}
You will be able to instantiate and access it. If you change it to:
namespace MyNameSpace
{
public class myclass
{
public static myMethod()
{
// Code
}
}
}
You will be able to call myClass.myMethod without instantiating a new myClass.
The short answer is that everything needs to be inside a class; I'd suggest you sit down with a basic tutorial to help you get to grips with the basics...
Code need to be inside classes.
It would look something like this:
using System;
namespace MyNameSpace
{
public class CommonHelper
{
public string FormatMyData(object obj)
{
//do something
return String.Empty;
}
}
}
If the function you call is not related to the forms, make it static
namespace myns
{
public static class myhelper
{
public static void DoSomething()
{
}
}
}
and call the method using myhelper.DoSomething();
If the function you want to call is somehow form-related, e.g. common functionality across multiple forms, derive a class from Form (does not need a visual form) and make it base class of the visual forms:
namespace myns
{
public class MyFormBase : Form
{
protected void DoSomethingWithTheForm()
{
}
}
}
and in your form's .cs:
namespace myns
{
public partial class MyFormName : MyFormBase
{
}
}

Categories