understanding func<T, TResult> C# - c#-3.0

I am trying to refactor some of my code to use Func
I have created a sample to try to understand how it works but I am getting compilation error. In the e.g. below when I am trying to access the parameter attributes or return the return value the compiler complain.
Clarifications please.
using System;
namespace chsarp
{
class Program
{
static void Main(string[] args)
{
ParamInput input = new ParamInput();
input.ReservationID = 10;
Test testMethod = new Test();
Func<ParamInput, ReservationResult> methodToInvoke = testMethod.GetStatus;
ReservationResult result = TestFn(methodToInvoke, input);
}
static Result TestFn<Param, Result>(Func<Param, Result> methodToInvoke, Param parameter) where Result : new()
{
Result result = new Result();
try
{
result = methodToInvoke(parameter);
}
catch (Exception exception)
{
result.status = string.Format("Error-{0} during reserving {1}",
parameter.ReservationID,
exception.Message);
}
return result;
}
}
class Test
{
public ReservationResult GetStatus(ParamInput msg)
{
ReservationResult result = new ReservationResult();
result.status = string.Format("The ReservationID-{0}", msg.ReservationID);
return result;
}
}
class ParamInput
{
public int ReservationID { get; set; }
}
class ReservationResult
{
public string status { get; set; }
}
}

Annotated compile errors:
error CS1061: 'Result' does not contain a definition for 'status'
error CS1061: 'Param' does not contain a definition for 'ReservationID'
Code using generic type arguments can only compile if the compiler knows the member of the generic type. It doesn't know that the Result type argument has a "status" member. It certainly doesn't if you invoke TestFn<object, object>().
You'll need to use a constraint to make this work. You already do, but new() isn't strong enough. Something like "where Result : IResult" for example, where IResult is an interface type that has a status property. Or a base class. The compiler can now be 100% sure that any allowed concrete instance of the generic method will execute without causing runtime errors. Since it can only ever be compiled when it was invoked with a type that has a "status" property.
All the same applies to the Param type argument. The usefulness of a generic method here rapidly disappears when you do this, it is not the proper usage. Unless you can leverage IResult, like you can IEnumerable.

Compiles...
You ought to descibe what you aim is in your question.
See Hans' answer for details that might help you understand the error.
Your problem is that you're saying the function should take a Result that is instantiable, but you are not saying it has to have a property called "status".
namespace chsarp
{
class Program
{
static void Main(string[] args)
{
Func<int, string> m = Test.GetStatus;
var t = TestFn(m, 10);
}
static string TestFn<TParam>(Func<TParam, string> m, TParam p)
{
try { return m(p); }
catch (Exception exception)
{
return string.Format("Reserving \"{0}\" failure exception: {1}", p, exception);
}
}
}
static class Test
{
public static string GetStatus(int inp)
{
return string.Format("The ReservationID-{0}", inp);
}
}
}

Related

run method and store it one variable before each test in Nunit

I need to run a method before each test Like how before method works in TestNg.
What I am expecting is I need to take the Testname and find the relevant test data and store it variable. Currently I have included that step in Test. But it would be good to have to reduce a line of code in each test.
is it possible in Nunit?
Setup attribute is used to provide a common set of functions that are performed just before each test method is called. You can also get the Method name from TestContext.CurrentContext.Test.MethodName. There are also other properties on Test like Arguments or FullName depending on what you need.
[SetUp]
public void Setup()
{
var testName = TestContext.CurrentContext.Test.MethodName;
TestContext.WriteLine($"SetUp for {testName}");
}
Alternately, you can also use TestCaseData class which provides extended test case information for a parameterized test.
public class DemoClass {
[TestCaseSource(typeof(MyDataClass), nameof(MyDataClass.DivideTestCases))]
public int DivideTest(int n, int d)
{
return n / d;
}
[TestCaseSource(typeof(MyDataClass), nameof(MyDataClass.AddTestCases))]
public int AddTest(int a, int b)
{
return a + b;
}
}
public class MyDataClass
{
public static IEnumerable DivideTestCases
{
get
{
yield return new TestCaseData(12, 3).Returns(4);
yield return new TestCaseData(12, 2).Returns(6);
yield return new TestCaseData(12, 4).Returns(3);
}
}
public static IEnumerable AddTestCases
{
get
{
yield return new TestCaseData(10, 15).Returns(25);
yield return new TestCaseData(12, 10).Returns(22);
yield return new TestCaseData(14, 5).Returns(19);
}
}
}

RxJava2: Using Flowable with zipWith

I'm trying to make the following code work me but something is wrong, here is a snippet:
private void myMethod() {
Flowable.fromIterable(cache)
.zipWith(this::doesExist, (record, exist) -> {
// do stuff
return true;
}).subscrib();
}
private Flowable<Boolean> doesExist(CacheRecord record) {
// Do something
return Flowable.just(true);
}
This doesn't compile, any idea?
UPDATE:
Any thoughts about the following snippet:
Flowable.fromIterable(m_cache) //
.flatMapCompletable(cachedStation -> {
return Single.zip(Single.just(cachedStation), doesIssueExist(cachedStation), (record, exist) -> {
System.out.println(cachedStation + ", " + exist);
return true;
}).toCompletable();
}).subscribe();
Your doesExist method requires a CacheRecord as a parameter. But the method reference you have given this::doesExist sends an instance of Subscriber<? super Object> that's why the incompatible type error is showing.
The expanded form of your method is given below.
private void myMethod() {
Flowable.fromIterable(cache)
.zipWith(new Publisher<Object>() {
#Override
public void subscribe(Subscriber<? super Object> s) {
doesExist(s);
}
}, (record, exist) -> {
// do stuff
return true;
}).subscribe();
}
Here, the first parameter to zipWith
new Publisher<Object>() {
#Override
public void subscribe(Subscriber<? super Object> s) {
doesExist(s);
}
}
is what you have shortened as this::doesExist
As you can see the zipWith requires the first parameter a Publisher, and you have created an anonymous Publisher, and in the subscribe method you are calling doesExist(s) by sending the Subscriber<? super Object> s, which is not the required type. Your method reference statement this::doesExist does exactly the above operation and that's why the incompatible type error is shown by the compiler.
If you are trying to zip the Flowable with the flowable returned by doesExist method, you can directly call it, without method reference, by passing a valid CacheRecord object as follows
Flowable.fromIterable(cache)
.zipWith(doesExist(anotherCache), (record, exist) -> {
// do stuff
return true;
}).subscribe();
Note: See method reference for more information
Update: If you are trying to pass the items emitted by fromIterable to doesExist method and get combined result boolean and cacheRecord, then
create a holder class as follows
class CacheRecordResult {
CacheRecord cacheRecord;
boolean isExist;
public CacheRecordResult(CacheRecord cacheRecord, boolean isExist) {
this.cacheRecord = cacheRecord;
this.isExist = isExist;
}
}
Then subscribe to CacheRecordResult as follows
private void myMethod() {
Flowable.fromIterable(cache)
.flatMap(cacheRecord -> doesExist(cacheRecord)
.map(exist -> new CacheRecordResult(cacheRecord, exist)))
.subscribe(cacheRecordResult -> {
CacheRecord cacheRecord = cacheRecordResult.cacheRecord;
boolean isExist = cacheRecordResult.isExist;
});
}

How can I dump the normal properties on an IEnumerable in Linqpad

If I have an object that among other things is an IEnumerable and I dump this object I get the enumerated values.
Is there a way to get Linqpad to list the other properties:
Se example below:
Can I get Dump to include Hello and digits properties?
void Main()
{
var t = new test();
var d = new Dictionary<string,string> {{"Hello","World"},{"Good by","Sky"}};
t.Dump();
d.Dump();
}
// Define other methods and classes here
public class test : IEnumerable
{
public string Hello { get { return "World"; }}
public List<int> digits { get { return new List<int> {0,1,2,3,4,5,6,7,8,9}; }}
public IEnumerator GetEnumerator() { yield return "Hej"; }
}
You could write a DumpPayload extension method as follows:
void Main()
{
var t = new test();
t.DumpPayload();
}
public static class Extensions
{
public static void DumpPayload (this IEnumerable o)
{
if (o == null)
{
o.Dump();
return;
}
var d = new Dictionary<string,object>();
foreach (var member in o.GetType().GetProperties())
try
{
d[member.Name] = member.GetValue (o, null);
}
catch (Exception ex)
{
d[member.Name] = ex;
}
d["AsEnumerable"] = o;
d.Dump();
}
}
If you put this extension method into "My Extensions", it will be available to all queries.
Another solution is to implement ICustomMemberProvider in the test class:
public class test : IEnumerable, ICustomMemberProvider
{
public string Hello { get { return "World"; }}
public List<int> digits { get { return new List<int> {0,1,2,3,4,5,6,7,8,9}; }}
public IEnumerator GetEnumerator() { yield return "Hej"; }
IEnumerable<string> ICustomMemberProvider.GetNames()
{
return "Hello Enumerator".Split();
}
IEnumerable<Type> ICustomMemberProvider.GetTypes ()
{
return new [] { typeof (string), typeof (IEnumerable) };
}
IEnumerable<object> ICustomMemberProvider.GetValues ()
{
return new object [] { Hello, this.OfType<Object>() };
}
}
Note that if the test class is defined in another assembly, you don't need to reference LINQPad in order to implement ICustomMemberProvider. You can just paste in the following definition into your project and LINQPad will pick it up:
namespace LINQPad
{
public interface ICustomMemberProvider
{
IEnumerable<string> GetNames ();
IEnumerable<Type> GetTypes ();
IEnumerable<object> GetValues ();
}
}
As far as I can tell if the object you're trying to dump implements IEnumerable then LINQPad always wants to dump it as an IEnumerable list. Getting rid of the interface correctly shows the Hello and digits properties in the dumped info.
Going from this link it appears you can write your own dump which accomplishes something like LINQPad by enumerating the collection and all it's properties then outputting the whole thing as an XHTML string. I haven't tried this.
Use a Serializer?
Json.NET will do all of this for you in a json format.
Newtonsoft.Json.JsonConvert.SerializeObject(t, Newtonsoft.Json.Formatting.Indented)
if you don't want json, then pick a serializer you do want, or you'll just have to do what a serializer would do, use reflection to iterate the properties on the object.

MVC source code singleton pattern

Why does .net MVC source code ControllerBuilder use a delegate to assign the controller factory?:
private Func<IControllerFactory> _factoryThunk;
public void SetControllerFactory(IControllerFactory controllerFactory) {
_factoryThunk = () => controllerFactory;
}
Why can't it just assign the ControllerFactory directly?, ie:
private IControllerFactory _factory;
public void SetControllerFactory(IControllerFactory controllerFactory) {
_factory = controllerFactory;
}
public void SetControllerFactory(Type controllerFactoryType) {
_factory = (IControllerFactory)Activator.CreateInstance(controllerFactoryType);
}
The reason that _factoryThunk is currently defined as a Func<IControllerFactory> is that it's a generic means to support both overloads:
void SetControllerFactory(Type);
void SetControllerFactory(IControllerFactory);
The implementation of the first one uses the fact that _factoryThunk is a Func by declaring that Func inline by using Activator to instantiate the Type lazily:
this._factoryThunk = delegate {
IControllerFactory factory;
try
{
factory = (IControllerFactory) Activator.CreateInstance(controllerFactoryType);
}
catch (Exception exception)
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, MvcResources.ControllerBuilder_ErrorCreatingControllerFactory, new object[] { controllerFactoryType }), exception);
}
return factory;
};
Therefore, the reason the other overload looks like it has a spurious implementation is that since _factoryThunk is declared as a Func, the line you propose wouldn't have even compiled:
_factoryThunk = controllerFactory;
_factoryThunk is a Func<IControllerFactory> whereas controllerFactory is an IControllerFactory -- incompatible types.

Tell me the flow of execution in the following scenario

public class Temp
{
List<T> values = new List<T>;
static Temp()
{
System.Console.WriteLine("static constructor");
}
public Temp()
{
System.Console.WriteLine("general constructor");
}
}
Also please explain me when will the List object will be created and with what type it is created.
}
It appears the field gets initialized first, then the static constructor is called, then the constructor.
class Test
{
string variable = new Func<string>(() =>
{
Console.WriteLine("field initializer");
return "VARIABLE";
})();
static string staticvariable = new Func<string>(() =>
{
Console.WriteLine("static field initializer");
return "STATICVARIABLE";
})();
static Test()
{
System.Console.WriteLine("static constructor");
}
public Test()
{
System.Console.WriteLine("general constructor");
}
}
Test t = new Test();
outuput:
static field initializer
static constructor
field initializer
general constructor
[edit]
Oops sorry, it was a non-static field and I didn't notice it.
The static ctor will be called first.
Then values list will be second and the the ctor.
Read about beforefieldinit here.