Generic list and static main - c#-4.0

using System;
using System.Collections.Generic;
namespace ConsoleApplication74
{
class Program<T>
{
public void Add(T X)
{
Console.WriteLine("{0}", X);
}
static void Main(string[] args)
{
Program<string> MyGeneric = new Program<string>();
MyGeneric.Add("ABC");
Console.Read();
}
}
I have erroe Program does not contain a static 'Main' method suitable for an entry point.
Program.cs properties has Build Action as Compile.
I have no idea what is wrong.

The Main method, or entry point in your program, cannot be in a class that has generic arguments. Your Program class has a T type argument. The C# specification calls this out in section 3.1 under Application Startup:
The application entry point method may not be in a generic class declaration.
You should make a new class instead of trying to use Program:
class Program
{
static void Main(string[] args)
{
MyClass<string> MyGeneric = new MyClass<string>();
MyGeneric.Add("ABC");
Console.Read();
}
}
class MyClass<T>
{
public void Add(T X)
{
Console.WriteLine("{0}", X);
}
}

Related

C# Class implementation with generics

Hi everyone I am studying C# but ran into some compiler errors:
I am getting the error: 'LinkedList' does not implement interface member 'IEnumerable.GetEnumerator()'
I think I did.
Below is the code:
using System;
using System.Collections.Generic;
namespace LinkedListGenericsExample
{
public class LinkedListNode<T>
{
//constructor
public LinkedListNode(T value)
{
//code here
}
//code here
}
//LinkedList class with generics. It inherit the IEnumerable class with
//generics. Should I use IEnumerable or IEnumerable<T>?
public class LinkedList<T>: IEnumerable<T>
{
//code here
}
public LinkedListNode<T> AddLast(T node)
{
//code here
}
public IEnumerator<T> GetEnumerator()
{
//code here
}
//here I think the GetEnumerator() method is implemented
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
//Trying this but not working. Also I am confused.
/*
IEnumerator IEnumerable<T>.GetEnumerator()
{
return GetEnumerator();
}
*/
//Main() below
}
I am using the Visual Studio Code to compile the code.
Error ecountered:
'LinkedList' does not implement interface member 'IEnumerable.GetEnumerator()'
Using the generic type 'IEnumerator' requires 1 type arguments
Using the generic type 'IEnumerable' requreis 1 type arguments
'IEnumerable' in explicit interface declaration is not an interface
Question:
1) Should I inherit the IEnumerable class or IEnumerable class with generic?
2) How can I implement the "IEnumerable.GetEnumerator()" It looks like the compiler is not recognized my GetEnumerator() implementation but I am not sure why....
Need some help here. Thank you!
Updating the complete code below. It works!!
using System;
using System.Collections; //using System.Collections instead
namespace LinkedListGenericsExample
{
//Linked list node class in Generics form
public class LinkedListNode<T>
{
//LinkedListNode constructor
public LinkedListNode(T value)
{
this.Value = value;
}
public T Value;
public LinkedListNode<T> Next {get; internal set;}
public LinkedListNode<T> Prev {get; internal set;}
}
public class LinkedList<T>: IEnumerable
{
public LinkedListNode<T> First {get; private set;}
public LinkedListNode<T> Last {get; private set;}
public LinkedListNode<T> AddLast(T node)
{
var newNode = new LinkedListNode<T>(node);
if (First == null)
{
First = newNode;
Last = First;
}
else
{
Last.Next = newNode;
Last = newNode;
}
return newNode;
}
public IEnumerator GetEnumerator()
{
LinkedListNode<T> current = First;
while(current != null)
{
yield return current.Value;
current = current.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/*
IEnumerator IEnumerable<T>.GetEnumerator()
{
}
*/
}
class Program
{
static void Main(string[] args)
{
//Console.WriteLine("Hello World!");
var list2 = new LinkedList<int>();
var list3 = new LinkedList<String>();
list2.AddLast(1);
list2.AddLast(3);
list2.AddLast(5);
//Go throuhg entire list of numbers
foreach(int i in list2)
{
Console.WriteLine(i);
}
Console.WriteLine();
list3.AddLast("2");
list3.AddLast("four");
list3.AddLast("foo");
//Go through entire list of strings
foreach(string s in list3)
{
Console.WriteLine(s);
}
}
}
}
Regarding your two questions, here are 2 cents.
1. I would suggest you implement the generic version. This would ensure type-safety and other benefits. You can read more on advantages of generics in this link. . Since you are learning C#, it would be a good idea to read about it.
Your implementation looks good.Please add reference to System.Collections namespace to your code for fixing the compile errors.
using System.Collections;

Execute an objects method without making a new instance

How can I execute Print from within TestObject?
class Program
{
private int Value;
static void Main()
{
TestObject test = new TestObject();
Program p1 = new Program();
Program p2 = new Program();
p1.Value = 1;
p2.Value = 2;
p1.Print();
p2.Print();
}
private void Print()
{
Console.Write(Value.ToString());
Console.ReadKey();
}
}
class TestObject
{
// How to execute p1.Print here?
}
There are multiple ways to do this:
Pass Program directly to TestObject
Pros:
Simple change
Cons:
You will have to make Print public
You will expose other things in Program
You're coupling TestObject to Program directly
Here's sample code:
class Program
{
static void Main()
{
TestObject test = new TestObject(this);
}
public void Print()
{
Console.Write(Value.ToString());
Console.ReadKey();
}
}
class TestObject
{
public TestObject(Program p)
{
p.Print();
}
}
Pass a delegate to TestObject
Pros:
Simple change
Doesn't have to make Print public
Only exposes 1 method to TestObject
Cons:
The coupling is TestObject wants to do something, not TestObject wants access to something that does something
Here's sample code:
class Program
{
static void Main()
{
TestObject test = new TestObject(() => Print());
}
private void Print()
{
Console.Write(Value.ToString());
Console.ReadKey();
}
}
class TestObject
{
public TestObject(Action print)
{
print();
}
}
Implement an interface in Program and pass it to TestObject
Pros:
Only exposes what the interface exposes
Easier to implement other places (better to say "need this interface" than "needs a delegate", clearer contract specification)
No coupling to a specific type, coupling is to any object that meets certain criteria - implements an interface
Cons:
None relevant (in my opinion)
Here's sample code:
interface IPrintable
{
void Print();
}
class Program : IPrintable
{
static void Main()
{
TestObject test = new TestObject(this);
}
public void Print()
{
Console.Write(Value.ToString());
Console.ReadKey();
}
}
class TestObject
{
public TestObject(IPrintable p)
{
p.Print();
}
}
Conclusion: My advice would be to pick the interface way. Clearer design, easier to extend without having multiple delegates being passed around.

MS TEst: Method not executed when base class is generic

Not duplicate of: Inherited test class from generic base is ignored in MSTest
In my case, the test classes are in the same namespace/assembly.
When unittesting classes which have a lot in common, I would like to use a base test class with a generic parameter. I have boiled the problem down to the following, where my base test method is not being executed, but ONLY in the generic case.
Non-generic: Base test method is EXECUTED:
[TestClass]
public class DerivedTestClass : BaseUnitTest
{
protected override string ReturnMeSomething(object obj)
{
return "test1" + obj.ToString();
}
[TestMethod]
public void derived_test()
{
// This is executed
}
}
[TestClass]
public abstract class BaseUnitTest
{
[TestMethod]
public void base_test()
{
// This is executed
}
protected abstract string ReturnMeSomething(object obj);
}
Generic: Base test method in generic base class is NOT EXECUTED:
[TestClass]
public class DerivedTestClass : BaseUnitTest<string>
{
protected override string ReturnMeSomething(string s)
{
return "test1" + s;
}
[TestMethod]
public void derived_test()
{
// This is executed
}
}
[TestClass]
public abstract class BaseUnitTest<T>
{
[TestMethod]
public void base_test()
{
// This is NOT executed
}
protected abstract string ReturnMeSomething(T t);
}
Can anyone tell me the reason for this?
After a few days, this suddenly works (!!). If anyone ever experiences this same, odd behavior, please write a comment here. I would suggest anyone to reboot and clean+rebuild everything and try again.

Postsharp - Adding OnMethodBoundaryAspect to abstract Method - Aspect Not Firing

I'm trying to implement an OnMethodBoundary aspect on an abstract method in an abstract class so that all types that inherit from this class will automatically have the aspect applied. There are no compilation errors or warnings, but the OnEntry method doesn't fire. Note: If I apply the aspect to a non-abstract method, everything works fine
here's the aspect example:
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, Inheritance = MulticastInheritance.Multicast)]
public sealed class DoSomethingAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
//Do work
}
}
// here's the abstract class
public abstract class Job
{
//...
[DoSomething]
public abstract void Run();
}
Updated answer: it doesn't matter where anything is, as long as both projects have Postsharp referenced then you're good to go.
It works just fine. Which version of PostSharp are you using?
class Program
{
static void Main(string[] args)
{
Job1 j = new Job1();
j.Run();
Console.ReadKey();
}
}
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, Inheritance = MulticastInheritance.Multicast)]
public sealed class DoSomethingAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("OnEntry");
}
}
public abstract class Job
{
//...
[DoSomething]
public abstract void Run();
}
public class Job1 : Job
{
public override void Run()
{
Console.WriteLine("Run method");
}
}
Results:
OnEntry
Run method

Adding static method to IronPython scope

Assume I have the following code:
public static class Foo
{
public static void Bar() {}
}
In IronPython, I would like to have:
Bar()
Without having to include the Foo on the line. Now, I know I can say:
var Bar = Foo.Bar
Bar()
But I would like to add Bar to the ScriptScope in my C# code using SetVariable. How can I do this?
Create delegate to method and set in to scope.
public class Program
{
public static void Main(string[] args)
{
var python = Python.CreateEngine();
var scriptScope = python.CreateScope();
scriptScope.SetVariable("Print", new Action<int>(Bar.Print));
python.Execute(
"Print(10)",
scriptScope
);
}
}
public static class Bar
{
public static void Print(int a)
{
Console.WriteLine("Print:{0}", a);
}
}

Resources