Use a public attribute in a static method on c# - c#

I created a plugin and I'm trying to use it on a class, the problem is that the method I'm trying to use in this class is a static method.
The struct of the plugin implementation is this:
The problem is in the method called TestMethod, on the TestClass class.
I can't use the attribute TestPlugin because it is not a static property.
I've tried to use it as static, but when I change this the TestPlugin property becomes null.
For this reason I tried to find a way to use it as a normal property, but after a lot of search I had not been able to find a way to do it.
The code is as follows:
TestPlugin declaration:
[ImportMany]
public IEnumerable<ITestPlugin> TestPlugin{ get; private set;}
Use of TestPlugin attribute:
private static void TestMethod(){
...
// Here Visual Studio says that :
//An object reference is required for the nonstatic field, method, or property 'ToastPlugin'
foreach(plugin in TestPlugin){
//Plugin's use
}
...
}
Edit:
Is there a way to use TestPlugin inside of TestMethod without declaring TestPlugin as static, for the reasons said before?

Is there a way to use TestPlugin inside of TestMethod without
declaring TestPlugin as static, for the reasons said before?
Quick answer is no.
Basically you have the following options:
Make TestPlugin static as well.
Make TestMethod not be static.
Make TestMethod take a reference to a TestClass object as a parameter.
Add a static collection of IList<IEnumerable<ITestPlugin>> and in the get/set methods of the TestPlugin add/remove the class from that new collection.
Which of those four you would choose depends upon exactly what you are trying to achieve.

Related

making an object accessible to child instances only

i have the following class
public class Manager
{
public SharedObject sharedobj {get;set;}
public SomeObject someobj {get;set;}
public AnotherObject anotherobj {get;set;}
//...
}
i want sharedobj to be only accessible from any instance that is in the Manager class instance
making it static is not an option since i will have multiple instances of the Manager class, so the only thing in my mind is sending the sharedobj to the constructors of each object that will use it, i was wondering if there is a better way to achive such thing without having to reference the sharedobj in each instance that will need to use it.
another way i thought of is using the protected keyword and make the other classes inherit the manager
protected (C# Reference):
The protected keyword is a member access modifier. A protected member is accessible within its class and by derived class instances. For a comparison of protected with the other access modifiers, see Accessibility Levels.
This is assuming you want each to have his own shared object that you can access if you have the manager.
On a side note, you could also use Dependency Injection (a.k.a DI) to do it. Here's the easiest, shortest explanation of DI I've seen so far: http://www.jamesshore.com/Blog/Dependency-Injection-Demystified.html .
It's a bit more advanced approach with it's own positives and negatives like everything else, but at least read the short link I've mentioned so you'll have an idea of what it is.
You will have to pass it to each object, just as you wrote. Either in the constructor or simply make a setter in SomeObject and AnotherObject, and use that. I would go with what you wrote, and pass it through the constructors.
On a sidenote, if nothing else but the objects within Manager should use SharedObject, then it probably should be private instead of public in the Manager class.

Static to instance, how do I handle properly?

I have a static class I am deprecating and modifying the class to force clients to use an instance variable.
Question is, how do I handle allowing the previous static class to remain and be used (with obsolete attribute) and also allow the new non static class to be used as well (same name, same method names)?
Is this possible?
There are several ways you can use, but none do exactly what you want:
Remove the static modifier, making it a normal non-static class, and optionally make it partial, implementing the new instance related code in a second file. With this method, however, you will not be able to obsolete the entire static class, as you have only one class.
Place the new class in a new namespace
Place the new class in a new project, but in the same namespace as the original
If you make all the old static members obsolete, I would go for option nbr. 1.
I don't think it will be possible to keep the same name and parameters but you could do this
[Obsolete("This class is obsolete; use class B instead")]
Visual Studio will hint to the user, that they should be using the new class.
Not possible with same class name and same members, the type would be ambiguous. This is frequently done using the obsolete attribute's message field to tell the caller what class to use instead, in this case, your new instance class.
You could come up with some convoluted versioned interface, perhaps, but even in the best case that would be unclear to callers and they would have to know which version they were dealing with. Callers need to handle an instace and static classes differently, so hiding which they are using would only lead to problems (were it possible to do so).
One thing you could do is to implement non-static versions of methods through an explicitly implemented interface, like this:
public interface ITest
{
string Foo();
}
// your class
public class Test : ITest
{
//original, static version of Foo
public static string Foo()
{
return "foo";
}
// Foo reimplemented as a non-static method
// note that you need to implement ITest explicitly
// for it to compile
string ITest.Foo()
{
return "foo";
}
}
This compiles and works as expected, except that the non-static methods can only be called through the interface, i.e.:
ITest t = new Test(); //assigning to a variable of type ITest
Console.WriteLine(t.Foo()); // writes "foo"
Console.WriteLine(Test.Foo()); // and calling the static method still works too

Why doesn't the MessageBox class have a default constructor in C#?

Case 1:
I am trying this
MessageBox m = new MessageBox();
And got compilation error
'System.Windows.Forms.MessageBox' has no constructors defined
Case 2:
Then, I have made a class without constructor
class myClass
{
}
and tried myClass my = new myClass(); This time I found no error.
Now, my question:
Why I am getting error in 1st case?
Since, both are classes and every class have default constructor, then
Where is default constructor in 1st case?
The constructor may be private or protected in order to forbid direct instantiation. Use the static factory method instead. There is a static method Show in the MessageBox class.
Archil is right, too. If theres a explicit constructor defined, the implicit default constructor is not created anymore.
And regarding x0ns comments: Yes, it's also impossible to instantiate static classes. Don't use static classes, thats poor design (there are exceptions).
In c#, evey class automatically has default constructor if NONE is defined. MessageBox defines other constructors, so it does not automatically have default constructor
MessageBox is designed to be used as a static class - see http://msdn.microsoft.com/en-us/library/79b3xss3(VS.80).aspx
You can make your class static using:
static class myclass {}
System.Windows.Forms.MessageBox has no default (empty) constructor.
A constructor can be hidden by setting its accessibility to something other than public.
The class' design declares that you can't use it as an object.
It only has static methods that can be used without instantiating an object of that class.
In case 1, MessageBox is a static class, it has no constructors (update - it has a private constructor says reflector but the OP gave a misleading/incorrect compiler error message.) Static classes are defined like this:
public static class MessageBox { }
A static class can only have static methods, and as such is not meant to be instantiated.
In case 2, MyClass is not a static class, and the compiler generates a default constructor for you if you don't define any constructors.
UPDATE: to all downvoters: go compile up a project with a static class and examine it in reflector - it decompiles without the static keyword becuase there is no MSIL or metadata for a static class; the compiler (in .net 2.0 or later) generates an abstract sealed class with no constructors. The keyword "static" is just syntactic sugar. Additionally, in 1.0/1.1 of .NET (when MessageBox was created,) the static keyword did not exist for classes and the sealed/private ctor was the accepted pattern.

Can one access TestContext in an AssemblyCleanup method?

In Microsoft's UnitTesting namespace (Microsoft.VisualStudio.TestTools.UnitTesting) there are AssemblyInitialize and AssemblyCleanup attributes you can apply to static methods and they will be called before and after all tests respectively.
[AssemblyInitialize]
static public void AssemblyInitialize(TestContext testCtx)
{
// allocate resources
}
[AssemblyCleanup]
static public void AssemblyCleanup()
{
// free resources
}
My question: is it possible and safe to access the TestContext within AssemblyCleanup()? If not, is storing resource references as static members a reasonable alternative or could that cause problems as well?
Additionally/optionally: what is the reasoning behind not passing a reference to the TestContext to clean-up methods?
I'm accessing a static property on the same class and it seems to be working fine. I'll update this answer if I encounter any problems. I am not, however, accessing the TestContext so I'm curious if that would work too.
You can't pass any paramaters to AssemblyCleanup method. Here's the error if you try to do so:
Result Message: Method
SomeNamespace.TestDatabaseInitializer.AssemblyCleanup has wrong
signature. The method must be static, public, does not return a value
and should not take any parameter.

Why can't you use the keyword 'this' in a static method in .Net?

I'm trying to use the this keyword in a static method, but the compiler won't allow me to use it.
Why not?
That's an easy one. The keyword 'this' returns a reference to the current instance of the class containing it. Static methods (or any static member) do not belong to a particular instance. They exist without creating an instance of the class. There is a much more in depth explanation of what static members are and why/when to use them in the MSDN docs.
As an additional note, from a Static method, you can access or static members of that class. Making the example below valid and at times quite useful.
public static void StaticMethod(Object o)
{
MyClass.StaticProperty = o;
}
Static methods are Class specific and not instance specific. "this" represents an instance of the class at runtime, so this can't be used in a static context because it won't be referencing any instance.
Instead the class's name should be used and you would only be able to access static members in the class
this represents the current instance object and there is no instance with static methods.
If You want to use non static function of class in static function.Create object of class in static function.
For Eg
Class ClsProgram(){
public static void staticfunc(){
ClsProgram Obj = new ClsPrograM()
Obj.NonStaticFunc();
}
public void NonStaticFunc(){}
}
There is no this object reference in the static method.
For OP's question, refer to the accepted answer. This answer is for the ones who're looking for a fast one liner to use in static methods.
If the class is a form, and it's open (you need the name of the form as well), this can be called within a static method;
Application.OpenForms["MainForm"];

Categories

Resources