C# method Linq variable return - c#

hope your help :)
I search to make the result of the LinQ Variable bellow "ES" available in an other method.
public void Contract_ES(QCAlgorithm Algorithm_ES, Slice slice)
{
foreach(var chain in slice.FutureChains)
{
var ES = (from futuresContract in chain.Value.OrderBy(x => x.Expiry)
where futuresContract.Expiry > Algorithm_ES.Time.Date.AddDays(1)
select futuresContract).FirstOrDefault();
}
}

I downloaded QuantConnect just to get an idea what you're trying to do. The example below should at least not yield any errors, but I haven't tried the output.
using QuantConnect.Data;
using System.Linq;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm
{
public interface IFuturesContractSelector_ES
{
FuturesContract GetFuturesContract_ES(QCAlgorithm Algorithm_ES, Slice slice);
}
public class Contract_ES : IFuturesContractSelector_ES
{
private readonly Slice _Slice;
private readonly QCAlgorithm _Algorithm_ES;
public Contract_ES(QCAlgorithm Algorithm_ES)
{
_Algorithm_ES = Algorithm_ES;
}
public Contract_ES(Slice slice)
{
_Slice = slice;
}
public FuturesContract GetFuturesContract_ES(QCAlgorithm Algorithm_ES, Slice slice)
{
foreach (var chain in slice.FutureChains)
{
if (chain.Value.Symbol.Value.StartsWith("ES"))
{
return (from futuresContract in chain.Value.OrderBy(x => x.Expiry)
where futuresContract.Expiry > Algorithm_ES.Time.Date.AddDays(1)
select futuresContract).FirstOrDefault();
}
}
return null;
}
}
}
Or you could do an extension on the Slice class:
using QuantConnect.Data;
using System.Linq;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm
{
public static class SliceExtensions
{
public static FuturesContract GetFuturesContract_ES(this Slice slice, QCAlgorithm Algorithm_ES)
{
foreach (var chain in slice.FutureChains)
{
if (chain.Value.Symbol.Value.StartsWith("ES"))
{
return (from futuresContract in chain.Value.OrderBy(x => x.Expiry)
where futuresContract.Expiry > Algorithm_ES.Time.Date.AddDays(1)
select futuresContract).FirstOrDefault();
}
}
return null;
}
}
public class Test
{
public void TestMyMethod(Slice slice)
{
var contract = slice.GetFuturesContract_ES(new QCAlgorithm());
//... do something
}
}
}

I tried to create an interface then the method, result is :
using QuantConnect.Securities;
namespace Quant
{
public interface IFuturesContractSelector_ES
{
void GetFuturesContract_ES(QCAlgorithm Algorithm_ES, Slice slice);
}
}
public class Contract_ES : IFuturesContractSelector_ES
{
private readonly Slice _Slice;
private readonly QCAlgorithm _Algorithm_ES;
public Contract_ES(QCAlgorithm Algorithm_ES)
{
_Algorithm_ES = Algorithm_ES;
}
public Contract_ES(Slice slice)
{
_Slice = slice;
}
public void GetFuturesContract_ES(QCAlgorithm Algorithm_ES, Slice slice)
{
foreach(var chain in slice.FutureChains)
{
if (chain.Value.Symbol.StartsWith("ES"))
{
var ES = (from futuresContract in chain.Value.OrderBy(x => x.Expiry)
where futuresContract.Expiry > Algorithm_ES.Time.Date.AddDays(1)
select futuresContract).FirstOrDefault();
}
}
return ES;
}
}
At the Line return ES, I get this error :
The name "ES" does not exist in the current context.
Weird because I have another method build in this way, with no prob -_-
Maybe using foreach statement that cause the non possible return of "var ES" ?

Related

Using Moq with NUnit in C#

I am building a simple Airport program where planes can only take off / land if the weather is sunny and not stormy. This depends on the Weather class (which randomises the weather between sunny and stormy). However, for my tests, I want to mock the weather so I can test for all cases.
Here is my Weather.cs:
using System;
namespace ClassNameWeather
{
public class Weather
{
public Weather()
{
}
public string Forecast()
{
Random random = new Random();
var weather = random.Next(1, 11);
if (weather == 1 || weather == 2)
{
return "stormy";
}
else
{
return "sunny";
}
}
}
}
Here is my Airport.cs:
using System;
using System.Collections.Generic;
using ClassNamePlane;
using ClassNameWeather;
namespace ClassNameAirport
{
public class Airport
{
private string _AirportName { get; set; }
public List<Plane> planes;
private Weather _weather = new Weather();
public Airport(string _airportName, Weather weather)
{
planes = new List<Plane>();
_AirportName = _airportName;
}
public void Land(Plane plane)
{
if (_weather.Forecast() != "stormy")
{
planes.Add(plane);
Console.WriteLine($"{ plane.Name } has landed at {_AirportName}");
}
else
{
throw new Exception("It's too stormy to land");
}
}
public void TakeOff(Plane plane)
{
if (_weather.Forecast() != "stormy")
{
planes.Remove(plane);
Console.WriteLine($"{ plane.Name } has departed from {_AirportName}");
}
else
{
throw new Exception("It's too stormy to take off");
}
}
public int GetPlaneCount()
{
Console.WriteLine($"Number of planes at {_AirportName}: {planes.Count}");
return planes.Count;
}
public void GetPlaneNames()
{
planes.ForEach(plane => Console.WriteLine((plane as Plane).Name));
}
public List<Plane> GetPlaneList()
{
return planes;
}
}
}
And here is the test that I'm trying to use the mock in:
using NUnit.Framework;
using ClassNameAirport;
using ClassNamePlane;
using ClassNameWeather;
using Moq;
namespace AirportTest
{
public class AirportTest
{
Airport airport = new Airport("TestAirport", weather);
Plane plane = new Plane("TestPlane");
[Test]
public void PlaneCanLand()
{
var weather = new Mock<Weather>();
weather.Setup(x => x.Forecast()).Returns("sunny");
airport.Land(plane);
Assert.IsTrue(airport.planes.Contains(plane));
}
public void PlaneCanTakeOff()
{
airport.Land(plane);
airport.TakeOff(plane);
Assert.IsFalse(airport.planes.Contains(plane));
}
}
}
This line: Airport airport = new Airport("TestAirport", weather); is not working, saying the name weather does not exist.
Can anyone help me to make sure I am using Moq correctly? I'm new to C# and any advice is much appreciated.
Thank you!
UPDATE
I have fixed this, but now receive the following error:
System.NotSupportedException : Unsupported expression: x => x.Forecast()
Non-overridable members (here: Weather.Forecast) may not be used in setup / verification expressions.
Does anyone know how to fix this please?
You can introduce interface IWeather like
public interface IWeather
{
string Forecast();
}
Than implement it in Weather class. Pass IWeather reference to AirPort class and setup a mock for that.
var weather = new Mock<IWeather>();
weather.Setup(x => x.Forecast()).Returns("sunny");
...
var airport = new Airport("TestAirport", weather.Object)
And do not initialize it in Airport class directly private Weather _weather = new Weather(); (your constructor argument is not used), do like this
public class Airport
{
private string _AirportName { get; set; }
public List<Plane> planes;
private readonly IWeather _weather;
public Airport(string _airportName, IWeather weather)
{
planes = new List<Plane>();
_weather = weather;
}
...
}
You have not declared the variable weather. I suggest that you create an Initialize method and attribute it with TestInitialze
[TestInitialize]
public void TestInitialize()
{
var weather = new Mock<Weather>();
var airport = new Airport("TestAirport", weather)
}

How do i get symbol references in a diagnostic without SymbolFinder?

Currently i've got this code:
private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
{
foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
{
var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
if (declaredSymbol is IFieldSymbol fieldSymbol)
{
// SymbolFinder.FindReferencesAsync()
var b = fieldSymbol.Locations;
// context.SemanticModel.Compilation.
}
}
return false;
}
And this scenario:
private static readonly string TestSourceImplementsDisposableAndDoesMentionDisposableField = #"
using System;
using System.IO;
namespace ConsoleApplication1
{
public class SampleDisposable : IDisposable
{
public void Dispose()
{
}
}
public class SampleConsumer : IDisposable
{
private SampleDisposable _disposable = new SampleDisposable();
private IDisposable _ms = new MemoryStream();
public void Dispose()
{
_disposable?.Dispose();
_ms?.Dispose();
}
}
}";
Ultimately my desire is to figure out whether a dispose method is accessing a disposable field. Unfortunately i can't seem to find a way to get this working without using SymbolFinder, which requires a solution.
I did something similar with SymbolFinder and it was an easy thing to do - but how do i do it from the functionality available within a diagnostic?
Am i missing something obvious here?
You could simply use the SemanticModel to analyse the type used for the field like this:
private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
{
foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
{
var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
if (declaredSymbol is IFieldSymbol fieldSymbol)
{
var isDisposeable = CheckIsTypeIDisposeable(fieldSymbol.Type as INamedTypeSymbol);
// SymbolFinder.FindReferencesAsync()
var b = fieldSymbol.Locations;
// context.SemanticModel.Compilation.
}
}
return false;
}
private string fullQualifiedAssemblyNameOfIDisposeable = typeof(IDisposable).AssemblyQualifiedName;
private bool CheckIsTypeIDisposeable(INamedTypeSymbol type)
{
// Identify the IDisposable class. You can use any method to do this here
// A type.ToDisplayString() == "System.IDisposable" might do it for you
if(fullQualifiedAssemblyNameOfIDisposeable ==
type.ToDisplayString() + ", " + type.ContainingAssembly.ToDisplayString())
{
return true;
}
if(type.BaseType != null)
{
if (CheckIsTypeIDisposeable(type.BaseType))
{
return true;
}
}
foreach(var #interface in type.AllInterfaces)
{
if (CheckIsTypeIDisposeable(#interface))
{
return true;
}
}
return false;
}
Basically you would search through all interfaces of the class and the base class recursively to find the type corresponding to IDisposeable - which should be somewhere in the hierarchy.

How can I return the collection of contained objects from a class

I Have a class Variable and another class Variables.
Variables class is used to maintain and generate the list of objects of the type Variable.
Everything is working ok and i am happy about it. But there is one thing i dont know how to get it done.
i want to use the Variables in foreach loop like this..
Variables oVariables;
foreach(Variable element in oVariables)
But i am not able to do this by just using the object of the class Variables in this example that is oVariable. i have to write some function that will return the Collection.
So is there any way i can avoid writing an extra function and get Collection from that.
Any Help is appreciated. Thanks
Here is the code of Variables Class.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualBasic;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace APVariable
{
public class Variables
{
private Collection mCol;
public Variable Add(string Name, object Value, string skey = "")
{
Variable objNewMember = new Variable();
objNewMember.Name = Name;
objNewMember.Value = Value;
if (skey.Length == 0)
{
mCol.Add(objNewMember);
}
else
{
try
{
Information.Err().Clear();
mCol.Add(objNewMember, skey);
if (Information.Err().Number != 0)
{
Information.Err().Clear();
mCol.Add(objNewMember);
}
}
catch { Information.Err(); }
{
}
}
return objNewMember;
objNewMember = null;
}
public int count
{
get
{
return mCol.Count;
}
}
//public void Remove(int vntIndexKey)
//{
// //this can be the int or the string.
// //passes the index or the key of the collection to be removed.
// mCol.Remove(vntIndexKey);
//}
public void Remove(dynamic vntIndexKey)
{
//this can be the int or the string.
//passes the index or the key of the collection to be removed.
mCol.Remove(vntIndexKey);
}
public dynamic newEnum
{
get
{
return mCol.GetEnumerator();
}
}
public Variable this[object vIndex]
{
get
{
Variable result = null;
try
{
result = (Variable)mCol[vIndex];
}
catch
{
}
return result;
}
}
//public IEnumerator GetEnumerator()
//{
// //this property allows you to enumerate
// //this collection with the For...Each syntax
// return mCol.GetEnumerator();
//}
public Variables()
{
mCol = new Collection();
}
~Variables()
{
mCol = null;
}
}
}
You'll need to implement the IEnumerable interface. This will allow to be able to use the foreach on your class. You should also use Colection.
It looks like you've started, you're almost there.
namespace APVariable
{
public class Variables : IEnumerable, IEnumerator
{
private Collection<Variable> mCol;
public Variable Add(string Name, object Value, string skey = "")
{
Variable objNewMember = new Variable();
objNewMember.Name = Name;
objNewMember.Value = Value;
if (skey.Length == 0)
{
mCol.Add(objNewMember);
}
else
{
try
{
Information.Err().Clear();
mCol.Add(objNewMember, skey);
if (Information.Err().Number != 0)
{
Information.Err().Clear();
mCol.Add(objNewMember);
}
}
catch { Information.Err(); }
{
}
}
return objNewMember;
objNewMember = null;
}
public int count
{
get
{
return mCol.Count;
}
}
//public void Remove(int vntIndexKey)
//{
// //this can be the int or the string.
// //passes the index or the key of the collection to be removed.
// mCol.Remove(vntIndexKey);
//}
public void Remove(dynamic vntIndexKey)
{
//this can be the int or the string.
//passes the index or the key of the collection to be removed.
mCol.Remove(vntIndexKey);
}
public dynamic newEnum
{
get
{
return mCol.GetEnumerator();
}
}
public Variable this[object vIndex]
{
get
{
Variable result = null;
try
{
result = (Variable)mCol[vIndex];
}
catch
{
}
return result;
}
}
public IEnumerator GetEnumerator()
{
//this property allows you to enumerate
//this collection with the For...Each syntax
return mCol.GetEnumerator();
}
public Variables()
{
mCol = new Collection<Variable>();
}
~Variables()
{
mCol = null;
}
}
}
</code>
</pre>
I'd recommend subclassing Collection or List or implementing IList or ICollection

Return results from lists of different type via interface c#

I have created an interface that in theory should be able to return multiple generic lists of different types to provide the client with various information. When I attempt to loop through the results of the list it is only able to return first collection, can you help me to understand how I should be returning results from the following:
Interface class:
public interface IExampleInterface{}
public class ExampleType : IExampleInterface
{
public int First;
public int Last;
}
public class ExampleAmount : IExampleInterface
{
public decimal Amount;
public decimal TotalFee;
}
public class ExampleFacts : IExampleInterface
{
public bool TooLow;
public bool TooHigh;
}
Interface provider:
public class ExampleInterfaceProvider
{
private static readonly string conn = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
public static List<IExampleInterface> ExampleResults(int id)
{
//declare variables, read from database query using ExecuteReader...
var sT = new ExampleType
{
First = first;
Last = last;
}
var sA = new ExampleAmount
{
Amount = amount;
TotalFee = totalFee;
}
var sF = new ExampleFacts
{
TooHigh = tooHigh;
TooLow = tooLow;
}
var exampleResults = new List<IExampleInterface> {sT, sA, sF};
return exampleResults;
}
}
On the page I need to return the data:
foreach (dynamic item in ExampleResults(0))
{
Response.Write(item.First.ToString())
Response.Write(item.Last.ToString())
//The first two for 'sT' read fine, it breaks here
Response.Write(item.Amount.ToString())
//... And so on
}
Any help would be much appreciated,
Thanks
I think, there is no another solution except comparing implementations;
foreach (IExampleInterface item in ExampleResults(0))
{
if (item is ExampleType)
{
var exampleType = (ExampleType)item;
Response.Write(exampleType.First.ToString())
Response.Write(exampleType.Last.ToString())
}
else if (item is ExampleAmount)
{
var exampleAmount = (ExampleAmount)item;
Response.Write(exampleAmount.Amount.ToString())
}
//... And so on
}
If you are using C# 7, you can perform it as switch case
foreach (IExampleInterface item in ExampleResults(0))
{
switch (item)
{
case ExampleType c:
Response.Write(c.First.ToString());
Response.Write(c.Last.ToString());
break;
case ExampleAmount c:
Response.Write(c.Amount.ToString());
break;
default:
break;
}
//... And so on
}
You can find the documentation.
So basically, the items implementing IExampleInterface should all be written to a Response in a way that is somewhat specific to the actual type implementing the interface?
Then how about this:
public interface IExampleInterface
{
void WriteTo(Response response);
}
public class ExampleType : IExampleInterface
{
public int First;
public int Last;
public void WriteTo(Response response)
{
response.Write(First.ToString());
response.Write(Last.ToString());
}
}
public class ExampleAmount : IExampleInterface
{
public decimal Amount;
public decimal TotalFee;
public void WriteTo(Response response)
{
response.Write(Amount.ToString());
response.Write(TotalFee.ToString());
}
}
public class ExampleFacts : IExampleInterface
{
public bool TooLow;
public bool TooHigh;
public void WriteTo(Response response)
{
response.Write(TooLow.ToString());
response.Write(TooHigh.ToString());
}
}
And then:
foreach (IExampleInterface item in ExampleResults(0))
{
item.WriteTo(Response);
}
Assuming that Response is a variable holding an instance of the response rather than a static class.

C# binary search tree

I was making a test case for some code on binary search tree my professor gave
public static void Main(string [] args)
{
//on my prof's code, public class BinSearchTree<T>
BinSearchTree<int> myTree = new BinSearchTree<int>();
myTree.Insert(10);
myTree.Insert(15);
myTree.Insert(5);
myTree.Insert(2);
myTree.Insert(1);
Console.WriteLine(myTree.ToString());
Console.ReadKey();
}
It compiles, but it displays
BinSearchTree`1[System.Int32]
Can somebody tell me why it displays that?
my prof's code:
public class BinSearchTree<T> where T : IComparable<T>
{
private class OurTreeNode<T>
{
public T Data { get; set; }
public OurTreeNode<T> Left;
public OurTreeNode<T> Right;
public OurTreeNode(T d = default(T), OurTreeNode<T> leftnode = null, OurTreeNode<T> rightnode = null)
{
Data = d;
Left = leftnode;
Right = rightnode;
}
public override string ToString()
{
return Data.ToString();
}
}
//...other methods
//prof's Insert method
public void Insert(T newItem)
{
mRoot = Insert(newItem, mRoot);
}
private OurTreeNode<T> Insert(T newItem, OurTreeNode<T> pTmp)
{
if (pTmp == null)
return new OurTreeNode<T>(newItem, null, null);
else if (newItem.CompareTo(pTmp.Data) < 0)
pTmp.Left = Insert(newItem, pTmp.Left);
else if (newItem.CompareTo(pTmp.Data) > 0)
pTmp.Right = Insert(newItem, pTmp.Right);
else
throw new ApplicationException("...");
return pTmp;
}
}
I tried adding a ToString() method after the Insert method but it gives me an error when I used foreach. Is there a way of displaying it without making too much extra methods?
The class is using the default (Object's) ToString() implementation. You have 2 options:
walk though the elements of the tree and print it yourself
ask the author to implement/override the ToString() method
Can somebody tell me why it displays that?
It displays that because ToString() prints the type definition.
Default implementations of the Object.ToString method return the fully qualified name of the object's type. (from the docs)
For instance, the following short program prints System.Collections.Generic.List`1[System.Int32], which is the type of List<int>.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main(string[] args)
{
List<int> myTree = new List<int>();
myTree.Add(10);
Console.WriteLine(myTree.ToString());
}
}
Here are the rudiments of how to override the ToString() method to produce some meaningful output.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main(string[] args)
{
BinSearchTree<int> myTree = new BinSearchTree<int>();
myTree.Insert(10);
myTree.Insert(15);
Console.WriteLine(myTree.ToString());
}
}
public class BinSearchTree<T> where T : IComparable<T>
{
private List<T> values = new List<T>();
// rest of class omitted for clarity
public void Insert(T val) {
values.Add(val);
}
public override string ToString() {
var result = string.Empty;
foreach(var v in values)
{
result += v + ", ";
}
return result;
}
}
Output
10, 15,
As you have created the object of BinaryTree Class and have not overridden the ToString() method inside BinaryTree Class. You have not created object of OurTreeNode class and not calling ToString() method overriden inside it. Hence it is giving you the default ToString() method output of BinaryTree Class.
BinSearchTree<int> myTree = new BinSearchTree<int>();
You are calling
Console.WriteLine(myTree.ToString());

Categories

Resources