Here is what I'm trying to setup
My class is named Inventory
I have a static function named List_Departments()
I would like to be able to add an additional function to modify the previous
For Example: Inventory.List_Departments().ToHTML() would return an HTML formatted string containing the data from List_Departments()
If possible i'd like to reuse the same code for another function such as List_Categories()
I would really appreciate a nudge in the right direction on this. I just can't seem to find the correct terminology/ search term to pull up the info I need. Thank you very much for your help, and sorry for the somewhat stupid question.
You need to make the List_Departments method return an object that has a ToHtml method.
Depending on what your exactly methods are returning, you might make a class called something like ObjectList, which would have a ToHtml method, and have the ListDepartments and ListCategories return instances of it.
Alternatively, and especially if your methods are returning existing classes such a DataTable, you could make an extension method for that class called ToHtml.
It sounds like what you're referring to is Extension Methods
Basically, your functions List_Departments() and List_Categories are returning some typed object correct? That being, the object returned would have to have a Method created in it's class definition called ToHTML(). If the two functions return the same type of object then, you only need to define it once. If they return two different types, then you will have to define the ToHTML() method on both return types class definitions.
Unless I'm missing something here, these two functions don't require the static modifier.
If the returning types are types that you don't have source code access to, then you can define an extention method for each type that will process the type of object being returned and can display the ToHTML() for it.
You didn't supply much info, but using Extension methods seems a good approach to me.
An example turning an string into an int:
public static class StringMethods {
public static int ToInt(this String subject) {
int result;
int.TryParse(subject, result);
return result;
}
}
Assuming List_Departments returns Department:
public static class DepartmentMethods {
public static string ToHtml(this Department subject) {
// Whatever you want to do.
}
}
If you do have acces to the internals of the type returned by List_Departments, you can also just add ToHtml there.
the search term you're looking for is Method Chaining :-)
http://www.bing.com/search?q=method+chaining
This is something along the lines of what jQuery does. Basically, you make an object that has all of the methods that you want to be able to chain. Then, using the builder pattern, you can chain all the calls together until you call some final "result" method (ToHtml in your case).
public class Inventory
{
private IEnumerable<Departments> departments;
private IEnumerable<Items> items;
public Inventory ListDepartments()
{
// load up departments to a class level field
return this;
}
public Inventory ListItems()
{
// load up items to a class level field
return this;
}
public string ToHtml()
{
// convert whichever enumerable was previously loaded to HTML
return stringBuilder.ToString();
}
}
That lets you do things such as:
inventory.ListDepartments().ToHtml();
The ToHTML() function is a function that acts on the type returned from List_Departments()
For example:
if Inventory.GetProduct(0) returns an int. You can use Inventory.GetProduct(0).ToString() because ToString() is a method of an integer type.
In order to do this, List_Departments() would have to return a custom object that has a method called ToHTML() say
public class Department() {
public HtmlDocument ToHTML() {
//Create the html document to return here
}
}
Related
What I want is to have a method that accepts a type as a parameter and cast a variable into that type within the method in C#
as an example I want to pass a UI element to this helper method and extract its DataContext's (which is bound dynamically at runtime) Description. I want to use this method in a more generalized manner so that I can pass in the DataContext's type also.
private String GetDescription(FrameworkElement element, Type type) {
return (element.DataContext as type).Description;
//or
//return ((type)element.DataContext).Description;
}
both the ways it ends up with a compile time error.
I tried using generics as well but it was not successful as i might not understood properly.
It would be really great if someone could explain how to do this in a simple manner.
Write a interface and implement it for your classes:
public interface IDescribable
{
string Description{get;}
}
Implement this object on your desired classes:
public class MyClass:IDescribable
{
// other members
public string Description{get; set;}
}
Then you could even write an extension method to extract the string:
public static string GetDescription(this FrameworkElement element)
{
var contextData= element.DataContext as IDescribable;
return contextData!=null
? contextData.Description
:"";
}
Or if you don't want implement interface use reflection:
private string GetDescription(FrameworkElement element)
{
var decProp= element.DataContext.GetType().GetProperty("Description");
return decProp!=null
?decProp.GetValue(element.DataContext)
:"";
}
I have many classes in a program but almost all of them have the same methods and call almost the same stored procedures in a SQL Server. The difference in the name is the name of the class ( "pa" + class + CRUD). Is there a way to create a common calling method?
I want to make a method that, called from, let's say, the Student class, would call "paStudentSelect" and return a Student object; and if the method is called from the Teacher class the called SP is "paTeacherSelect" and return a Teacher object.
Extra: I have to check for nulls that vary from class to class. Using a string array as a parameter would be possible to check the properties of the class named in the string array?
PS: I know the thing to do is refactor and think again the code, the tables and the SPs but it's not my program.
As you've described your class name, this should do it:
var proc_name = string.Format("pa{0}delete", GetType().Name);
Extra: yes. Using reflection you can get a PropertyDescriptor for the class named in the string array or, if you want, the Type array...
var types = new Type[] { typeof(Student), typeof(Teacher), ... };
foreach(var t types)
{
// todo: perform your null checks here
var proc_name = t.Name;
db.ExecuteSQLCommandOrWhatever(proc_name);
}
I don't see why you would want to do such a thing. You say that you want to be able to call a common method from different classes(Student, Teacher, etc). If you were calling the method from a common place it made more sense to create a common method but when you are actually calling the method from the classes themselves you might as well call the appropriate SP and avoid the pitfalls with the type of approach you should take(code breaks with name changes and possibly more).
If you absolutely have to do this I can think of two possible solutions:
1) Extension Methods: create a common abstact type(you probably have one already) for your classes and add an extension method for that abstract class. The method could be something like this:
protected void CallCRUD(this AbstractType obj)
{
//call SP on this.TableName
}
2) Generic Method: create a static generic method:
public static T CallCRUD<T>()
{
//call SP on typeof(T).Name
}
Your "Extra:" is very vague so I don't have an answer for you there.
Problem: I have an entity class (base class), from which I inherit multiple times. Now I have an Add-method and a Validate-method in all of my derived classes. These functions are identical in all derived class and they are static.
Here is my Add-method
public static long Add(DBData[] UserData)
{
SortedDictionary<string, DBData> Data = new SortedDictionary<string, DBData>();
foreach (DBData d in UserData)
{
Data.Add(d.FieldName, d);
}
if (Project.Validate(Data, OperationMode.Add))
{
return DBUtility.Insert("Project", VSCommon.Serialise(Data));
}
else
{
return -1;
}
}
Now where I have "Project" in above function (2 places, one if object of type Project this function belong too, and other is the database table name). These are the only differences in all my derived classes. I want to put this Add-method in my base class, so I can skip writing it multiple times in every derived class.
I search and found that some try to use generics but I didn't seem to pick it up as when I use generic declaration. When I call the Validate-method a compilation error came by. Also, I need the name of the class as string to get relevant table name.
Not sure I am able to define my problem, any help is appreciated. Thanks.
You could add a (abstract in base class & virtual) method that returns "Project" for this class and some other string for the other classes. Then just reference that from the static Add method.
I think you could also use reflecion to get the "Project" string, if needed. However I'd advise against doing this, because it adds unnecessary coupling between your database and your code.
I solve my issue using following change in ADD Function
public static long Add<T>(DBData[] UserData)
{
SortedDictionary<string, DBData> Data = new SortedDictionary<string, DBData>();
foreach (DBData d in UserData)
{
Data.Add(d.FieldName, d);
}
MethodInfo m = typeof(T).GetMethod("Validate");
bool r = (bool)m.Invoke(null, new object[] { Data, OperationMode.Add });
if (r)
{
return DBUtility.Insert(typeof(T).Name, VSCommon.Serialise(Data));
}
else
{
return -1;
}
}
And then I have to change my call to Project.Add<Project>(...); or Client.Add<Client>(...); instead of Project.Add(...) before. But that save lot of trouble for me finally :).
EDIT: I just realize that Project.Add<Client>(...) can also be called and this will insert into Client object. This is not good, so my problem is not actually solved :(.
I have seen multiple tutorials that show C# method creation with parentheses containing parameters or simple empty. I have also seen a C# method written with out parentheses.
public int Value {
get{ return _Value; }
set{ _Value = value; }
}
I haven't tested out that code but is this allowed? Is it considered bad form?
That is a Property and not a method. If you create a Method then it requires ().
As in Philip's answer, your example code is actually a Property,
But you perhaps have hit on something that many actually miss and that is that Properties are implemented using one or two methods. They get created for you by the compiler and contain the contents of each of the get and/or set blocks.
So, a property of:
public string Name {
get {
return "Fred";
}
}
Is a nicer way of writing:
public string GetName() {
return "Fred";
}
Parentheses are mandatory when declaring or invoking a method.
As others have said, what you've shown there is a property, which is implemented as one or two methods behind the scenes (one for each of the "getter" and "setter").
However, you will sometimes see method names without parentheses - these are called method groups and are used to construct instances of delegate types.
For example:
public void Foo(string x)
{
...
}
...
Action<string> action = Foo;
Here Action<string> is a delegate type representing a call with a single string parameter and a void return type. This assignment creates an instance of that delegate type which will call the Foo method when it's invoked, e.g.
action("Test");
will call Foo with an argument of "Test".
That is a property, not a method. A method requires parenthesis.
Bad form depends on context, there are a few design considerations to take into account when deciding to use a property or not.
MSDN has a nice list here: http://msdn.microsoft.com/en-us/library/ms229006.aspx
Extending methods to any instance is really easy:
public static string LeaveJustNumbers(this string text)
{
return Regex.Replace(text, #"[\D]", "");
}
...
string JustNumbers = "A5gfb343j4".LeaveJustNumber();
But what if i want to extend methods to a sealed class like string, to
work like:
string.Format("Hi:{0}","Fraga");
Is there any way to do it?
If you're talking about 'extending' static methods (or replacing existing ones), then as far as I know, no, you can't do it and I'm not sure why you'd want to.
The main point of extension methods is so that the calling style is that of an method call on the instance. It allows for more elegant syntax and method chaining, amongst other things. LINQ without extension methods would be horrendously painful, for example.
You have three options, one of which is extremely horrible:
Make a normal extension method that makes the call on the static method
public static string SomeExtensionMethod(this string name)
{
return string.Format("Hi:{0}", name);
}
Usage:
Console.WriteLine("Mr Smith".SomeExtensionMethod());
Create a static helper class and make the call using that
Console.WriteLine(MyHelperClass.SomeMethod("Mr Smith"));
And the evil one
Create a static helper class with the same name as the type you want to 'extend' (e.g. public class String) ... then duplicate the static target method's signature (Format) and watch everyone cry hot salty tears of confusion when they see a type named "string" that isn't from the "System" namespace and they have to smatter their .cs file with using String=MyCrazyHacks.String and/or explicit namespaces.
I'm not even sure if you could do this to "string" as it's an alias for System.String, so I've changed the example to use the name "String" instead.
namespace MyCrazyHacks
{
public static class String
{
public static System.String Format(
System.String str, params object[] zeParams)
{
// do bad, unspeakable things that confuses everyone
return System.String.Format(....);
}
}
}
Note: please don't do this because you will cause great suffering...