Customize "quick fix" behaviour in Visual Studio - c#

I'm on Visual Studio for Mac 8.0.9 and would like to change the behaviour of several "quick fixes" (the options in the menu when I hit ALT + enter).
Specifically, I'd like to change the Create and initialize field 'myParam' option.
Right now it does this:
/// before quickfix
public class Test
{
public Test(object myParam) { }
}
/// after quickfix:
public class Test
{
public readonly object myParam
public Test(object myParam)
{
this.myParam = myParam
}
}
In our code base we're using underscores for private fields, as inspired by these naming conventions. Therefore I'd like to change the behaviour to this:
/// after quickfix:
public class Test
{
public readonly object _myParam
public Test(object myParam)
{
_myParam = myParam
}
}
Is this possible?
[Edit]
Things I tried:
looked for an option like the one described in the accepted answer
here. Seems to be no UI option in VS Mac
Tried configuring a .editorconfig file as described
here. Tried putting
it in the solution root as well as one of the root of one of the
containing project, but it doesn't seem to work for me

Related

For C# Project, how to raise a custom build error if someone tries to use specific method from framework class?

For a C# Project, I want to include a build step or something integrated in project that should raise build error if any developer is trying to use a specific method from framework classes, instead I want developers to use extension method for same. However I want to impose this as the compile time error. As an example, for a name sake I want developer on given project not to use string.Intern, instead should always use string.SpecialIntern. What are different ways to achieve this? I tried to use Roslyn-code-analysis but could not really write working rule for this, so I am not sure if tha'ts the right solution to this problem. Can someone guide me in details how to solve this with some examples?
This sounds like something you could accomplish with a custom code analyzer. I haven't tried it yet, but I believe it is possible to write your own analyzers.
This article from Microsoft claims to tell you how to do it:
https://learn.microsoft.com/en-us/visualstudio/extensibility/getting-started-with-roslyn-analyzers?view=vs-2017
Here's a direct link to the tutorial referenced in that article:
https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/tutorials/how-to-write-csharp-analyzer-code-fix
AFAIK there's no way to achieve what you're trying to do.
However, a solution would be to simply call the extension method.
public static class Extension
{
public static bool DoStuff(this Class stuff)
{
return false;
}
}
public class Class
{
public bool DontCallMe()
{
return this.DoStuff();
}
}
Class myClass = new Class();
myClass.DontCallMe();
Obviously, that only works if you can change the code of your class (which I suppose you aren't able to)
If that method is marked as virutal, you could create a Wrapper-Class which overrides that method.
public static class Extension
{
public static bool DoStuff(this Class stuff)
{
return false;
}
}
public class Class : Base
{
public override bool DontCallMe()
{
return this.DoStuff();
}
}
public class Base
{
public virtual bool DontCallMe()
{
return false;
}
}
Another approach would be to do what I described in this this post.

Can't create methods in a c# class ( Visual studio 2017)

please i just encountered this problem and i dont know how to go about it. I've tried to reset Visual studio settings to no avail.
I just created a new class and when i try to create a method in it, i get the following errors;
property or indexer must have at least one accessor,
property or indexer cannot have a void type
the problem is that i'm actually trying to create a method and not a property.
below is the class
public static class IoCContainer
{
public static void Setup
{
}
}
I don't know if i mistakenly toogle a visual studio setting or something.
The problem is that you're missing the parenthesis after Setup. Changing to the following should fix your issue:
public static void Setup()
{
}
The compiler thought you were trying to create a Property due to the missing parens.
You are missing parentheses () at the end of your function name.
So your code should be:
public static class IoCContainer
{
public static void Setup()
{
}
}

Renaming all variables and literals without obfuscation

I want to rename all the classes and variables in my code to make it more obfuscated. For example, this sample code:
public class Dog
{
public Dog()
{
Bark(4);
}
private void Bark(int times)
{
//Do something
}
}
becomes:
public class Cat
{
public Cat()
{
Wood(4);
}
private void Wood(int asdasd)
{
//Do something
}
}
If this is not possible, perhaps something even simpler where we simply add a character to the middle of every variable/name:
public class Do1g
{
public Do1g()
{
Bar1k(4);
}
private void Bar1k(int time1s)
{
//Do something
}
}
The functionality stays the same, and it is human-readable; however, all information on variable namings, classes, methods, etc, are changed.
Is there a way to obfuscate, while maintaining readability?
You can use Visual Studio Code Model to rename symbols. For example, to add 'x' to the current function name:
EnvDTE.TextSelection ts = DTE.ActiveWindow.Selection as EnvDTE.TextSelection;
EnvDTE80.CodeElement2 func = ts.ActivePoint.CodeElement[vsCMElement.vsCMElementFunction]
as EnvDTE80.CodeElement2;
func.RenameSymbol(func.Name + "x");
(You can run this code with Visual Commander or use in your own extension).
This rename operation also updates all references. You can naturally expand this sample to rename classes, namespaces and process files, projects.
Firstly I have no idea how this could ever be used but, in the comments you said that creating a new object that looks like the desired object is acceptable so
Here is my proposal
Read all the methods of the class using reflection
Create a List with all the properties's and methods's names from step 1
From there you can create a new object using LINQ with the names created from the list you created.
Keep in mind I don't know how or even if this would work.

How to extend instantiated class method

I am trying to extend a class method that comes from a compiled DLL, and am trying to do this from inside of an MVC project. However, for some reason, it does not pick this up.
This is how i usually extend an instantiated class method, as an example:
public static string CSVEncode(this string original)
{
//.......
}
With this, if i have any string, i can see and call the CSVEncode() method from the object itself, like this as an example:
string temp = "some string goes here";
string csv = temp.CSVEncode();
However, in this latest attempt it simply does not work...
Here's a small definition of the object I am trying to extend for this question's purposes (e.g.: there are more properties and methods that don't need to be iterated here).
namespace SomeOtherDLL.HumanRace
{
public class Human
{
//... some properties...
public Human(){ }
public bool CanAccess(string AppName)
{
//....
}
}
}
In my MVC solution, i have a Common project which includes a class called Extensions. In this class is where i put all my extensions, including the one I am trying to perform for the object above.
However, this does NOT show up in Intellisense anywhere afterwards, and if i try to build or compile, i get an error saying that this method does not exist, and i simply do not understand why?
namespace MyProj.Common
{
public static class Extensions
{
public static bool CanAccess(this HumanRace.Human original, int AppID)
{
//...some code here...
}
}
}
Now from what i can tell of the other object extensions i've done in the past, this should work perfectly...
Here's an example of how i try to use it in a View page:
#model SomeOtherDLL.HumanRace.Human
#using MyProj.Common.Extensions
#Html.Raw(Model.CanAccess(59) ? "<img src='CanAccess.jpg' />" : "<img src='CannotAccess.jpg' />")
.............
This does not resolve in Visual Studio... am I doing something wrong here?
Your Extensions class is in the namespace MyProj.Common, but you don't seem to be including that in your view. Try adding
#using MyProj.Common
to your view.

Skipping a whole test class in xUnit.net

Is it possible to skip all tests from a specific class like in NUnit
[TestFixture]
[Ignore("Reason")]
public class TestClass {
}
No - there is no such facility at present, and the last time it was requested it was considered too low value to add,
One quick way of achieving the effect in xUnit is to comment out the public - private classes are not reflected over (obviously it won't appear on the skip list that way though).
UPDATE: Another way is to put a TraitAttribute on the class and then (assuming you're using the xunit.console runner) filter it out by running with /-trait traitName. (e.g. you can achieve ExplicitAttribute, some aspects of the BDD frameworky technique of Pending tests and similar semantics that way - of course the big problem is they don't show up in any reports when using any of these filtering techniques)
UPDATE 2: You can do
const string skip = "Class X disabled";
[Fact(Skip=skip)]
void Test() {}
Then you can change to to const string skip = null to undo the skip. The (dis)advantage of this is that the test is still shown as a Skipped test in the test list, generally with a reason included in the test run report (vs making it private which makes it likely to be forgotten)
Here is my hack to avoid error xUnit1000: Test classes must be public (checked on single Fact, I think Theories can be hacked this way, too).
// Uncomment to enable tests
//public class FactSwitch : FactAttribute { } // public! ahh, a bug!
// Uncomment to disable tests
internal class FactSwitch : Attribute { }
public class MyTests
{
[FactSwitch]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
(3 years later)
While searching for the same solution I found there are better ways to do the same.
Let's rewrite the example above in a way Ruben Bartelink suggested (continuation of his idea).
public class MyTests
{
//const string SkipOrNot = null; // Run all tests
const string SkipOrNot = "reason"; // Skip all tests
[Fact(Skip = SkipOrNot)]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
Nathan Cooper suggested a good improvement for my idea:
public class MyTests
{
// Uncomment to disable tests
//private class FactAttribute : Attribute { }
[Fact]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
So I like both ideas from Ruben and Nathan. There is a subtle difference between using Skip="something" (Ruben) and not using Skip at all. Using "Skip" will put all your tests in a "Skipped tests" warning zone, while "FactAttribute : Attribute" will hide them.
I've found yet another way of temporary disabling entire class without compiler warning.
Disabled:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
/*
public /**/class DatabaseTests
{
}
to enable move the /* one line up (i.e. using alt+up):
/*
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
public /**/class DatabaseTests
{
}
Note that using full namespace path for SupressMessage does not mess up with your usings.
You need to set the your class access level as as internal and surpress message as #Miq did:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]
internal class MyClassThatIsNotATestClass
{ ... }
You can create LocalOnlyFactAttribute
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => base.Skip = value; }
}
As far as I know, the simplest way to dynamically skip a whole xUnit test class at runtime is to use the TestFrameworkAttribute at the assembly level, to point to a class that implements the ITestFramework interface (or inherits from XunitTestFramework, which is simpler) and which overrides the CreateDiscoverer() method to return another class, that implements the ITestFrameworkDiscoverer interface (or inherits from XunitTestFrameworkDiscoverer, which is simpler), where you can finally override the IsValidTestClass() method, to decide whether a class should be skipped or not.
Here is some sample code:
[assembly: TestFramework("MyNamespace.Xunit.MyTestFramework", "MyAssembly")]
namespace MyNamespace.Xunit
{
public class MyTestFramework : XunitTestFramework
{
public MyTestFramework(IMessageSink messageSink)
: base(messageSink)
{
}
protected override ITestFrameworkDiscoverer CreateDiscoverer(
IAssemblyInfo assemblyInfo)
=> new MyTestFrameworkDiscoverer(
assemblyInfo,
SourceInformationProvider,
DiagnosticMessageSink);
}
public class MyTestFrameworkDiscoverer : XunitTestFrameworkDiscoverer
{
public MyTestFrameworkDiscoverer(
IAssemblyInfo assemblyInfo,
ISourceInformationProvider sourceProvider,
IMessageSink diagnosticMessageSink,
IXunitTestCollectionFactory collectionFactory = null)
: base(
assemblyInfo,
sourceProvider,
diagnosticMessageSink,
collectionFactory)
{
}
protected override bool IsValidTestClass(ITypeInfo type)
=> base.IsValidTestClass(type) &&
FilterType(type);
protected virtual bool FilterType(ITypeInfo type)
{
// Insert your custom filter conditions here.
return true;
}
}
}
Tested with xUnit 2.4.1.
We are using it in Pomelo.EntityFrameworkCore.MySql (see AssemblyInfo.cs and MySqlXunitTestFrameworkDiscoverer.cs) (a bit more complex than the sample code here).
You could achieve this through a custom ITestClassCommand.
See http://mariangemarcano.blogspot.be/2010/12/xunitnet-running-tests-testcategory.html
Here's another hack that requires minimal changes to code
using FactAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
using TheoryAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
Any compatible attribute can be used for the replacement.
If you also use the InlineDataAttribute then you'll need to define a replacement as I don't think there's an existing compatible attribute.
using InlineDataAttribute = DummyDataAttribute;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
internal class DummyDataAttribute : Attribute
{
public DummyDataAttribute(params object[] data)
{
}
}
Adding a reason almost after one year after the initial question. I have a set of tests which are calling real server apis, and I would like to run then on demand. With nUnit, it has Ignore attribute : with that set, test runner will skip those tests, but I can still manually run it.
xUnit has no such feature. The nearest one is setting such a class level attribute, and comment it out when I want to run it.
Consider creating LocalOnlyFactAttribute, which can be reused across multiple test files.
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => this.Skip = value; }
}

Categories