I tried to ask a question yesterday but it was seemingly too vague. Here's another try.
In the past, I have used some winforms/VB.Net classes with functionality for, say, working on text strings, for file operations, or for database handling, like clsStrings, clsIO and clsDB. The idea was that these classes did everything related to the subject, so that clsStrings would have a method called "filterString", removeCertainChars" etc.
In the old winforms application, I simply wrote Imports clsStrings when I needed to access a method. Throughout the .vb file, I could then write something like
str = filterString(TextBox1.Text)
I now try to get the same functionality in a new winforms app in C#. The only thing I get to work is creating a variable for the class:
clsStrings clsstrings = New clsStrings();
...and then later in the code:
str = clsstrings.filterString(TextBox1.Text);
So I guess what I would want is the ability to use a using statement for these "helper classes" (is there a better word for them?) so that I wouldn't have to write the variable name all the time. (Just like when Intellisense discovers that a namespace is missing and asks if I want to have a using statement for, say, System.Data so I can write "DataTable" instead of having to write "Data.Datatable" all the time.)
I suspect I would need to put these class files in a separate folder or so, but that would be totally fine. I just want some structure to my app.
I hope this is clearer.
Thanks for any input!
Well, the difference is that now you are working with OOP principles.
What you could do to be closer to what you were used to is to build static classes for the helper class, maybe even turn them into extension methods.
Example:
public static class ClsStrings
{
public static string FilterString(this string stringToFilter) { return something; }
}
Then you could call it like this:
string filteredString = TextBox1.Text.filterString();
or
string filteredString = ClsStrings.filterString(TextBox1.Text);
Extension methods is the way to go here. Using these you can basically exten String class with your own methods and do something like Sting.filterString();
http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx
Related
I have a VSTO (Excel) project written in C#. Three questions:
I have a lot of variables that are populated once and then referenced extensively throughout the project. So I created a public static class which I called "Omni" - since that is both descriptive and short. Is something like this the recommended approach?
I put common functions in a public static class that I named "Utilities". I then used the "this" keyword as the first parameter, making them extension methods. They can then be accessed from anywhere - without using a "Utilities." prefix (although I'm not exactly sure why). Same question: is this the preferred way of doing this?
Finally, I have some common 'subroutines', i.e., public void methods. So parameters are passed in and processed, but nothing is returned. Should such common code just go in its own appropriately named public static class and then get called with the class name as a prefix? If so, is there any convention as to what the name of the class would be?
I realize these are newbie type questions (and I have been searching for a while!). Thanks.
Regarding your points
I have a lot of variables that are populated once and then referenced
extensively throughout the project. So I created a public static class
which I called "Omni" - since that is both descriptive and short. Is
something like this the recommended approach?
Yes, it is common practise to centralize for example string constants that
are often used.
If you have more of those, I would start to structure those to different
classes.
If you want that to be flexible and e.g. have cases where there are
mappings between constants, like Green = 1, I would move to some
enumeration value technology.
More on that idea can be found in this article
If the value does not change between different starts of your application,
check if you can use resources for that, which is often a good choice
for string constants to.
I put common functions in a public static class that I named
"Utilities". I then used the "this" keyword as the first parameter,
making them extension methods. They can then be accessed from
anywhere - without using a "Utilities." prefix (although I'm not
exactly sure why). Same question: is this the preferred way of doing
this?
Extension methods are a handy way of getting things like conversions done.
Just do not everything as an extension, just conversions as a rule of thumb.
Finally, I have some common 'subroutines', i.e., public void methods.
So parameters are passed in and processed, but nothing is returned.
Should such common code just go in its own appropriately named public
static class and then get called with the class name as a prefix? If
so, is there any convention as to what the name of the class would be?
This, in opposite of the others, looks like a design flaw.
Perhaps you can provide more information on what those subroutines do.
In object oriented code, code is distributed near the objects it is working
with. If you depend heavily on code that is in static classes, probably there
is something wrong. Do your static classes have members? Do they share some
knowledge between different calls to your static classes?
I've built a reusable Class Library to encapsulate my Authentication logic. I want to be able to reuse the compiled *.dll across multiple projects.
What I've got works. But, something about how I'm making the reference, or how my Class Library is structured isn't quite right. And I need your help to figure out what I'm doing-wrong/not-understanding...
I've got a Class Library (Authentication.dll) which is structured like this:
namespace AUTHENTICATION
{
public static class authentication
{
public static Boolean Authenticate(long UserID, long AppID) {...}
//...More Static Methods...//
}
}
In my dependent project I've added a reference to Authentication.dll, and I've added a using directive...
using AUTHENTICATION;
With this structure I can call my Authenticate method, from my dependent project, like so...
authentication.Authenticate(1,1)
I'd like to be able to not have to include that "authentication." before all calls to methods from this Class Library. Is that possible? If so, what changes do I need to make to my Class Library, or how I'm implementing it in my dependent project?
In C# a function cannot exist without a class. So you always need to define something for it, being a class for a static method or an object for an object method.
The only option to achieve that would be to declare a base class in the Authentication assembly from which you inherit in the dependent projects.
You could expose Authenticate as a protected method (or public works too), and call it without specifying the class name.
public class MyClassInDependentProject : authentication
{
public void DoSomething(int userId, long appId)
{
var success = Authenticate(userId, appId);
…
}
}
That said, you'll quickly find this to be a bad design. It conflates a cross-cutting concern with all sorts of other classes, and those classes are now precluded from inheriting from any other class.
Composition is a core principle of object-oriented programming, and we have the idiom "Favor composition over inheritance." This simply means that we break down complexity into manageable chunks (classes, which become instantiated as objects), and then compose those objects together to handle complex processing. So, you have encapsulated some aspect of authentication in your class, and you provide that to other classes compositionally so they can use it for authentication. Thinking about it as an object with which you can do something helps, conceptually.
As an analogy, think about needing to drill a hole in the top of your desk. You bring a drill (object) into your office (class). At that point, it wouldn't make sense to simply say "On," because "On" could be handled by your fan, your lamp, your PC, etc. (other objects in your class). You need to specify, "Drill On."
If you are making a class library in C# you should learn to use the naming conventions that exists: Design Guidelines for Developing Class Libraries
Here is how you should name namespaces: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface
C# is also an object oriented language, hence the need of classes (using Authentication as you should name your class).
It also seems like the data source is hard coded. Your class library users (even if it's just you) might want to configure the data source.
Google about singleton and why it's considered to be an anti pattern today (in most cases).
You are obliged to use Class in order to invoke your method, just
When is static class just NameClass.Method
When is not static, you must create instance, ClassName ob = new ClassName(); ob.Method();
The format of a call like this is class.method, and you really can't escape using the "class" moniker even with the "using" designation. Something has to "host" the function.
I don't think what you are asking for is possible without using the base class method Jay mentioned. If all you want is to simplify the syntax whenever you call Authenticate() however, this silly solution (adding an extra method in each class that needs to do authentication) may be just what you want:
private static void DoAuth(long UserID, long AppID){
authentication.Authenticate(UserID, AppID)
}
If the ID's are always the same within some context, you could also overload it:
private static void DoAuth(){
DoAuth(1,1)
}
Yes, this does mean you have to add more code wherever you want to do the authentication (that's why it's silly! ;) ). It does also however, also reduce this:
authentication.Authenticate(1,1);
...into this:
DoAuth();
I leave the cost / benefit analysis of this up to you..
I know I am some 3 years late but here goes nothing.
To keep your code cleaner and more readable you should create a new namespace for all the re-usable code that you want to have. Then in that namespace have the Authentication Class and Authenticate Function.
To use this you can easily set a using on your namespace and use the function as you are doing like
Authentication.Authenticate()
But to use
Authenticate()
by itself you can always do
using MyNamespace.Authentication;
and in your code use Authenticate Function directly.
Right now i am moving code around and rewriting a library. Unfortunately design was wrong and or unfinished so i have a bunch of functions calling a static method in my lib. I dont want to do namespace.class.subclass.method everytime. I tried using method = namespace.class.subclass.method everytime but that doesnt work for static methods and only classes/namespaces.
So i'd like to hack a alias for this file or the namespace. Just until i clean everything up. Is it possible? perhaps by passing in a compile flag or setting a few options?
If you are planning to migrate these from static to instance methods, why not simply write the desired end result as an adapter to the existing static methods, then slowly migrate to using the adapter and, finally, incorporate the actual code into the adapter class.
public class StaticAdapter
{
public void Foo()
{
StaticNameSpace.StaticClass.StaticSubclass.Foo();
}
}
used as
var adapter = new StaticAdapter();
adapter.Foo();
As you create new code use the adapter and as you touch old code, convert to use the adpater. Once the adapter holds all the references to the existing code, you're good to start changing the adapter to incorporate the code directly and retire the old static class.
How about adding
using namespace;
Then, you have to type class.subclass.methodName();
Without changing your library, I believe this is as good as it gets.
I have a class:
public class SomeClass {
// properties and methods here
}
Ideally I'd like to send the entire class to a string so I can render it in a view. The best way I can think of doing this, is to have a build script run and send it all to static text files, then reference those text files in the code. Is there a better way to do this? I'd like to be able to say:
return View(SomeClass.SourceToString());
I'm hoping I'm not missing a really obvious way to accomplish this.
C# is compiled into MSIL. There is no direct way to access the original source other than referencing the original source file.
You could use reflection to enumerate all the members of the class and emit each member's declaration/definition to a StringBuilder, and then return the built string.
I'm afraid there is nothing straightforward, and the reflection will give you a "reinterpreted" form of the code, with different structure, no comments, no body for methods...
Maybe you could save a "copy" of your code using a post-build script and resolve it when the SourceToString method is called.
I think you should really explain why you would a such like thing ? Maybe we will be able to suggest you a better solution.
I found myself having to remove the first line of a string quite often while working on a text parser in C#. I put together a simple function to do that for me, but coming from a PHP background, I have no idea where to put it since I can't define a function outside a class. What's a customary way of doing that in .NET? Do I create a static class to store my function?
I generally make a Helper or Utility static class and then put corresponding helper functions in there.
Additionally, I try to keep the Helper and Utility classes grouped logically - putting the text parsing functions alongside the object conversion functions is nonsensical. The confusion is cleared up with a TextUtils class and a ConversionUtils class.
Yes, static helper classes are usually the way to do this.
Also, in C# 3 you can declare the method like this:
public static string RemoveFirstLine(this string s) {
...
}
to make it an extension method. Then you can call it on any string as if the method was declared on the string type itself.
Be careful!
Generic utility functions which are cross cutting should live in a higher utility namespace. String parsing, File manipulation, etc.
Extension objects should live in their own namespace.
Utility functions that apply to a specify set of business objects or methods should live within the namespace of those objects. Often with a Helper suffix, ie BusinessObjectHelper. Naming is important here. Are you creating a container for miscellaneous methods, or would it make more sense to group them into specialized objects, ie a parser?
I don't think there's a standard for this. I tend to make a static class called BlahUtil. For your example, I'd make it a static method on StringUtil. This helps me group related methods into sensible units, making it easier to discover them and share them across teams.
You can also then choose which of these methods are exposed as extension methods (since c# 3.0):
public static class StringUtil
{
public static string RemoveFirstLine(this string multiLineString)
{
// ...
}
}
If you are using C# 3.0, you might want to consider using an extension method!
public static class StringExtensions
{
public static string RemoveFirstLine(this string myString)
{
return myString.Remove("line..!");
}
}
Then in code you can do this:
string myString = "Hello World etc";
string removedLineString = myString.RemoveFirstLine();
Usually I create a Utilities class and define static helper methods.
I've done the static "helper" classes but after some analysis; this type of helper function always ends up as a distinct class implementation. In your case you'd have a "basic text parser" class and a derived class that overrides the "parse" method.
I'd create a static worker class for such functions. Maybe not the nicest way, but the one which keeps things simple... ;)
K
Use an extension method for a string. That's what they are for.
You can use a class with static methods. Something like ParserUtils.RemoveFirstLine(). On .NET 3.5 and above you can sometimes use extension methods when your utility functions are related to a class you cannot modify, like the String class. Intellisense will show the extension method on any string object in the project.
Extensions are the way to go in those case. It literally add your function to the occurence. Only thing is that it's not possible to do static method in 2008.