I have created a public static class utils.cs I want to use it in other classes without prefixing method with utils, what\'s the syntax to do this ?
As a minimum, you have to specify at least the class name. All the using directive does is allow you to leave off the namespace. You can also use the using directive to specify an alias Instead of the entire namespace.class name, but then you have to use the alias...
using MyClassName = Namespace.MySubNS.OtherNameSpace.OriginalClassname;
MyClassName X = new MyClassName();
In this thread there are some questioning and argumenation about not using global methods, but I would like to add that there is another kind of scenario when static imports are desirable, i.e. when you want to bring some constants into scope. For example, if I want to construct SQL statements, I would prefer to not use duplicated string literals, as in this code example (using dynasql):
DBQuery.Select()
.Field("CustomerID")
.Count("OrderID")
.From("Orders")
.GroupBy("CustomerID")
.OrderBy("CustomerID")
.WhereField("OrderDate", Compare.GreaterThan, DBConst.DateTime(ordersAfter))
I would prefer doing this:
public class OrderTable {
public const string Orders = "Orders";
public const string CustomerID = "CustomerID";
public const string OrderID = "OrderID";
public const string OrderDate = "OrderDate";
}
...
DBQuery.Select()
.Field(OrderTable.CustomerID)
.Count(OrderTable.OrderID)
.From(OrderTable.Orders)
.GroupBy(OrderTable.CustomerID)
.OrderBy(OrderTable.CustomerID)
.WhereField(OrderTable.OrderDate, Compare.GreaterThan, DBConst.DateTime(ordersAfter))
If I would be using the suggestion by Loadmaster (Oct 16 at 16:49) then I could do this:
using O = TestingDynasql.OrderTable;
...
DBQuery.Select()
.Field(O.CustomerID)
.Count(O.OrderID)
.From(O.Orders)
.GroupBy(O.CustomerID)
.OrderBy(O.CustomerID)
.WhereField(O.OrderDate, Compare.GreaterThan, DBConst.DateTime(ordersAfter))
However, I would prefer to bring the constant into scope without any repeated but needed name and dot qualifer at all (as you can do with Java's static imports) i.e. do this:
DBQuery.Select()
.Field(CustomerID)
.Count(OrderID)
.From(Orders)
.GroupBy(CustomerID)
.OrderBy(CustomerID)
.WhereField(OrderDate, Compare.GreaterThan, DBConst.DateTime(ordersAfter))
But it is not possible to use this kind of syntax with C# ?
By the way, does anyone know of a better .NET library for creating SQL than dynasql, which does not seem to be designed for being independent of the SQL execution (as the problem described here: http://dynasql.codeplex.com/Thread/View.aspx?ThreadId=81988) ?
/ Sven
I suppose you could make all of your methods in utils.cs as extension methods to the object class, but you'd still have to prefix your methods with "this.", which is probably not what you want.
The "proper" (from an OO point of view of bringing a member into scope, is to IMPLEMENT it within the scope:
static class MySpecialStuff
{
public static int MySpecialValue { get {...} }
}
class MyWorkingClass
{
private static int MySpecialValue { get { return ySpecialStuff.MySpecialValue; } }
}
Now in the remainder of MyWorkingClass
(or in derived classes if you change the private to protected) you can reference MySpecialValue
thousands of times without any additional qualifications.
What Jon Skeet is not telling you is that you can have global static members in c#. Your utility class can indeed become a reality in c#.
Unfortunately, Microsoft has determined that the very process of constructing such members as above mere "normal" development, and requires that you forge them from raw intermediate language. Such a powerful pattern is above common syntax highlighting and friendly icons).
Here is the requisite sequence of utf-8 characters (guard it carefully):
.assembly globalmethods {}
.method static public void MyUtilMethod() il managed
{
ldstr "Behold, a global method!"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
(You could compile this example by invoking ilasm.exe from the SDK command prompt, remembering to use the /dll switch)
ilasm.exe output:
Microsoft (R) .NET Framework IL Assembler. Version 2.0.50727.4016 Copyright (c) Microsoft Corporation. All rights reserved. Assembling 'globalmethods.msil' to DLL --> 'globalmethods.dll' Source file is ANSI
global.msil(7) : warning -- Reference to undeclared extern assembly 'mscorlib'. Attempting autodetect
Creating PE file
Emitting classes:
Emitting fields and methods: Global Methods: 1;
Emitting events and properties: Global Writing PE file Operation completed successfully
Once you have compiled your newly created assembly (as "globalmethods.dll" for example), it's just a matter of adding a reference in Visual Studio. When that is complete, you better be sitting down, because it will be time to write some real code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace TestGlobalMethod
{
class Program
{
static void Main(string[] args)
{
"MyUtilMethod".Call();
Console.ReadKey();
}
}
/// <summary>
/// Reduces the amount of code for global call
/// </summary>
public static class GlobalExtensionMethods
{
public static void Call(this string GlobalMethodName)
{
Assembly.Load("globalmethods")
.GetLoadedModules()[0].GetMethod(GlobalMethodName)
.Invoke(null,null);
}
}
}
Yes, you just called a Global method in c#.
*Please don't use this, it's for example only :-) Also, you could probably write your global methods in another language that support them, such as VB.NET.
There's no way of doing this in C# - no direct equivalent of Java's static import feature, for example.
For more information about why this is the case, see Eric Lippert's post on the topic and a similar SO question.
In certain circumstances, however, it may make sense to write extension methods which live in non-nested static classes but "pretend" to be instance methods of a different class. It's worth thinking carefully before you introduce these, as they can be confusing - but they can also improve readability when used judiciously.
What sort of utility methods were you thinking of?