Today someone showed me a code snippet and I am wondering how its working:
//using System;
//using System.Collections.Generic;
//using System.Text;
namespace ConsoleApplication1
{
class Test
{
int i = 0;
}
class Program
{
static void Main(string[] args)
{
Test obj = new Test();
obj.ToString();
}
}
}
My question is if we have commented the above namespaces, how is the ToString() method still associated to the object obj?
Every class in C# inherits Object class, in which ToString is defined
Related
I want to add Debug and Trace to a class that I've created. However, I don't know where in my code to initialize a Trace Listener.
Here is the code I want to add to my static class:
Trace.Listeners.Add(
new TextWriterTraceListener(
File.CreateText("log.txt")
)
);
Trace.AutoFlush = true;
Here is the class to which I want to add the Trace Listener:
using System;
using System.Diagnostics;
using System.IO;
namespace Example.Shared
{
public static class ExampleClass
{
public static string SaySomething()
{
Trace.WriteLine($"I'm gonna say something");
return "Something";
}
// etc.
}
}
Apart from this class, I have only created some unit tests using Xunit. I have not yet created the application that will use this class.
This is what the unit test code looks like:
using Example.Shared;
using Xunit;
namespace ClassLibTests
{
public class ExampleClassTests
{
[Fact]
public void TestSaySomething()
{
string expected = "Something";
string actual = ExampleClass.SaySomething();
Assert.Equal(expected, actual);
}
// etc.
}
}
I execute the above tests at the command line with the command dotnet test.
In order to initialize any static class or static members of a class you can use static constructors. So, you can update your code as follow:
using System;
using System.Diagnostics;
using System.IO;
namespace Example.Shared;
public static class ExampleClass
{
static ExampleClass()
{
Trace.Listeners.Add(
new TextWriterTraceListener(File.CreateText("log.txt"))
);
Trace.AutoFlush = true;
}
public static string SaySomething()
{
Trace.WriteLine($"I'm gonna say something");
return "Something";
}
// etc.
}
For more details check:
C# static class constructor
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors
BTW, I've also updated code to use the newly introduced file scoped namespace. Less indentation.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/file-scoped-namespaces
In my current software I make use of serialization and therefore need everything to be marked with the [Serializable] attribute.
Is there an easy way of checking this using my Visual Studio without going through them one at a time, or just waiting for it to crash?
To clarify, I don't need to know how to check if a class is serializable in code. I'm talking about using the IDE.
If you want to use reflection to find classes not marked [Serializable] you can use reflection to get the class types via GetTypes and then find only those not marked with Serializable.
try this:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectOnSerializableAttr
{
class Program
{
static void Main(string[] args)
{
//use Linq
var q = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && ((t.Attributes & TypeAttributes.Serializable) != TypeAttributes.Serializable)
select t;
q.ToList().ForEach(t => Console.WriteLine(t.Name));
Console.ReadKey();
}
}
[Serializable]
public class TestSerializableOne
{
public string SomeFunc() { return "somefunc"; }
}
public class TestForgotSerializable
{
private int _testInt = 200;
}
}
The above program outputs:
Program
TestForgotSerializable
I have a very simple question. This being said, I have tried to solve it by searching through stackexchange's previously answered questions but I came up short. This is because I want to know how to tell the program's entry point to access other classes.
I had previously written a simple finite state machine but the code got congested because I did not know how to break it up into classes. In my new program, I am trying to break it up so it can be better managed.
The entry point starts off by accessing the class I created, NewState(). If you run the code, you will observe that despite it compiling correctly, the function inside NewState() does not produce the Console.WriteLine statement I wanted it to.
So, my question is this:
How do I make my code access the static void State() method within the NewState class and display the Console.WriteLine statement?
Program class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Finite_State_Machine_3
{
class Program
{
static void Main(string[] args)
{
new NewState();
}
}
}
NewState class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Finite_State_Machine_3
{
class NewState
{
static void State()
{
Console.WriteLine("Hello world");
}
}
}
The method is static, so instead of creating an instance, make the State method public and try this
static void Main(string[] args)
{
NewState.State();
}
But if you're going to be calling it like that, you'd probably be better off putting it in the same class.
class Program
{
static void Main(string[] args)
{
State();
}
static void State()
{
Console.WriteLine("Hello world");
}
}
If you do want it in a separate class and call it from an instance of that class, you need to make the State method non-static (as well as public) and call it from the instance
class Program
{
static void Main(string[] args)
{
NewState MyVariable = new NewState();
MyVariable.State();
}
}
class NewState
{
public void State()
{
Console.WriteLine("Hello world");
}
}
If it's static, then you'll call it from the class not from the instance.
So,
NewState.State()
That said, if I remember my design patterns right you actually want to be passing instances around, not using static methods.
You need to make the method public static or internal static, then just call it by invoking NewState.State()
The following code is not compilable:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args) { }
}
class Class : Class.Interface
{
internal interface Interface
{
}
}
}
The error message is:
error CS0146: Circular base class dependency involving 'ConsoleApplication1.Class' and 'ConsoleApplication1.Class.Interface'
Don't understand this.
Update:
This is probably more "motivating" (-;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args) { }
}
class Container : Container.Interface
{
// Everything, that is of type "Container.Interface" can be used as child here.
// ... including the container itself.
Interface[] _children;
// Is nested to keep the naming consistent.
internal interface Interface
{}
}
}
Wenn I put the interface outside of class "Container", it should be named somthing like "ContainerChildInterface". In my project I will have several classes like this, and thus several interfaces. And I think, using nested interfaces would be much better style in this case.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Collections;
using System.ComponentModel;
namespace ConsoleApplication1
{
class BreakingChange
{
delegate void SampleDelegate(string x);
public void CandidateAction(string x)
{
Console.WriteLine("Snippet.CandidateAction");
}
public class Derived : BreakingChange
{
public void CandidateAction(object o)
{
Console.WriteLine("Derived.CandidateAction");
}
}
static void Main()
{
Derived x = new Derived();
SampleDelegate factory = new SampleDelegate(x.CandidateAction);
factory("test");
}
}
}
\Program.cs(32,38): warning CS1707: Delegate 'ConsoleApplication1.BreakingChange.SampleDelegate' bound to 'ConsoleApplication1.BreakingChange.Derived.CandidateAction(object)' instead of 'ConsoleApplication1.BreakingChange.CandidateAction(string)' because of new language rules
\Program.cs(23,25): (Related location)
\Program.cs(16,21): (Related location)
Question:
I know what causes this warning and know the reason behind it. However, I don't know what the
best way to fix it?
1> Redefine the function (i.e.) change the function signature
2> Can we explicitly call BreakingChange.CandidateAction in the following line?
SampleDelegate factory = new SampleDelegate(x.CandidateAction);
Well, there are multiple ways to "fix" this, depending on what you want to, and can, do.
Personally I would add another overload to Derived that took a string, since you're going to have the same issue with non-delegate calls as well.
public class Derived : BreakingChange
{
public new void CandidateAction(string x)
{
base.CandidateAction(x);
}
public void CandidateAction(object o)
{
Console.WriteLine("Derived.CandidateAction");
}
}
Or, since you know you want the base class method, you can cast the reference x:
new SampleDelegate(((BreakingChange)x).CandidateAction)