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;
});
}
Related
I'd like to serialize a call using ethers, but only partially.
contract MockCall {
struct VoteResults {
uint256 votes;
bytes data;
}
event LogParam(uint256 param);
event LogParam(string name);
event LogParam(VoteResults[] results);
bool public isAction1 = false;
bool public isAction2 = false;
//I've only created this method so type chain would generate method stub
function Action(uint256 param1, string calldata name) public {
isAction1 = true;
}
// Intentionally leave 2 calldata parameters to verify appending calldata can work with trailing dynamic parameter
function Action(uint256 param1, string calldata name, VoteResults[] calldata voteResults) public {
isAction2 = true;
emit LogParam(param1);
emit LogParam(name);
emit LogParam(voteResults);
}
}
I would like to partially build the calldata, and my contract is going to handle injecting the rest of the parameters.
I've tried a few ways:
This way throws an error, in hexify, and sometimes json
let encodedFunctionCall = '';
try {
const rawInterface = new Interface("Action(uint256,string,(uint256,bytes)[]");
encodedFunctionCall = rawInterface.encodeFunctionData("Action(uint256,string,(uint256,bytes)[]", [BigNumber.from(5), "Abra"]);
}
catch(err) {
console.log(err);
}
This doesn't compile since it expects 3 parameters
const encodedFunctionCall = mockCall.interface.encodeFunctionData("Action(uint256,string,(uint256,bytes)[])", [BigNumber.from(5), "Abra"])
How do I partially construct calldata?
I am switching from async tasks to rxjava2 and have some issues with my code tests.
I have a room table of elements that have a certain monetary amount. On a usercontrol that is called DisplayCurrentBudget, a sum of all amounts should be displayed. This number must refresh everytime a new element is inserted. I tackled the requirement in two ways, but both produce the same result: My code does not care if the database is updated, it only updates when the fragment is recreated (onCreateView).
My first attempt was this:
//RxJava2 Test
Observable<ItemS> ItemObservable = Observable.create( emitter -> {
try {
List<ItemS> movies = oStandardModel.getItemsVanilla();
for (ItemS movie : movies) {
emitter.onNext(movie);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
DisposableObserver<ItemS> disposable = ItemObservable.
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribeWith(new DisposableObserver<ItemS>() {
public List<ItemS> BadFeelingAboutThis = new ArrayList<ItemS>();
#Override
public void onNext(ItemS movie) {
// Access your Movie object here
BadFeelingAboutThis.add(movie);
}
#Override
public void onError(Throwable e) {
// Show the user that an error has occurred
}
#Override
public void onComplete() {
// Show the user that the operation is complete
oBinding.DisplayCurrentBudget.setText(Manager.GetBigSum(BadFeelingAboutThis).toString());
}
});
I already was uncomfortable with that code. My second attempt produces the exact same result:
Observable<BigDecimal> ItemObservable2 = Observable.create( emitter -> {
try {
BigDecimal mySum = oStandardModel.getWholeBudget();
emitter.onNext(mySum);
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
DisposableObserver<BigDecimal> disposable = ItemObservable2.
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribeWith(new DisposableObserver<BigDecimal>() {
#Override
public void onNext(BigDecimal sum) {
// Access your Movie object here
oBinding.DisplayCurrentBudget.setText(sum.toString());
}
#Override
public void onError(Throwable e) {
// Show the user that an error has occurred
}
#Override
public void onComplete() {
// Show the user that the operation is complete
}
});
Any obvious issues with my code?
Thanks for reading, much appreciate it!
Edit:
I was asked what Manager.GetBigSum does, it actually does not do much. It only adds BigDecimal-Values of an Item list.
public static BigDecimal GetBigSum(List<ItemS> ListP){
List<BigDecimal> bigDList = ListP.stream().map(ItemS::get_dAmount).collect(Collectors.toList());
return bigDList.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
Further, I simplified the query. But it still does not care about DB updates, only about fragment recreation:
Single.fromCallable(() -> oStandardModel.getItemsVanilla())
.map(Manager::GetBigSum)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(e.toString())
);
Your rx logic has no error. That should be internal error in your getWholeBudget.
But why you write rx so complex?
For your case, you can just write:
Single.fromCallable(() -> oStandardModel.getItemsVanilla())
.map(Manager::GetBigSum)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(sum.toString()),
e -> log.error(e));
I solved it this way:
oStandardModel.getItemJointCatLive().observe(this, new Observer<List<ItemJointCat>>() {
#Override
public void onChanged(#Nullable final List<ItemJointCat> oItemSP) {
Single.fromCallable(() -> oStandardModel.getWholeBudget())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(e.toString())
);
}
});
My mistake was that I assumed RXjava2 does not need an onchanged event...now i just use onchanged event of livedata observer to trigger a simple rxjava2 query.
Do you think there is anything wrong with that approach?
I'm working with EF 4.5 and DbContext. At business rules layer level, I should implement checks to avoid change entity value properties in some entity scenarios. Sample: StartProjecteDate should be readonly if ProjectIsStarted but not in other status.
I follow DRY principle, for this reason, I should be able to inspect readonly properties list from context and also from UI.
My question:
Is there a DataAnnotation validator that can dynamically set properties as readonly?
(and if not, is there a different / better solution to this problem?)
Notice than I'm working with Web Forms (and Telerik) architecture, a clean and elegant pattern will be welcome.
I'm trying to set and get at run time EditableAttribute as Jesse Webb explains, but I'm not able to get dataannotation attributes from property, my code:
<EditableAttribute(False)>
<MaxLength(400, ErrorMessage:="MÃ xim 400 caracters")>
Public Property NomInvertebrat As String
Edited Nov 8 2013 after digging docs, it seems that dataanottions if for class but for instance object itself. Perhaps an iReadonlyableProperties interface may be a way.
I have a class containing extension methods that lets me read data annotations like this:
int maxRefLen = ReflectionAPI.GetProperty<Organisation, String>(x => x.Name)
.GetAttribute<StringLengthAttribute>()
.GetValueOrDefault(x => x.MaximumLength, 256);
So if you use it you should be able to do get the value of the EditableAttribute like this:
bool isEditable = ReflectionAPI.GetProperty<Foo, String>(x => x.NomInvertebrat)
.GetAttribute<EditableAttribute>()
.GetValueOrDefault(x => x.AllowEdit, true);
As for setting the data annotations at run-time, I haven't done it myself but I have read that there is a solution here: Setting data-annotations at runtime
Getting a list of all data annotations of a particular type I think would entail reading the entity framework metadata. Again I haven't tried this.
If you add that together I personally think it feels clunky rather than elegant, but you have asked for a solution using DataAnnotations and something more elegant would probably mean getting into your architecture.
I would be inclined to do this:
public bool StartDateIsReadOnly
{
//use this property client-side to disable the input
get{ return Project.IsStarted;}
}
//Implement IValidatable object to do server side validation
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext
{
bool startdateIsChanged = // I'll leave you to work out this bit
var results = new List<ValidationResult>();
if(StartDateIsReadOnly && startdateIsChanged)
results.Add(new ValidationResult("Start Date cannot be changed after project is started");
}
Here is the ReflectionAPI class:
Please note that the class includes part of a hack that #JonSkeet posted and described as "evil". I personally think this bit ain't so bad, but you should read the following references:
Override a generic method for value types and reference types.
Evil code - overload resolution workaround
public static class ReflectionAPI
{
public static int GetValueOrDefault<TInput>(this TInput a, Func<TInput, int> func, int defaultValue)
where TInput : Attribute
//Have to restrict to struct or you get the error:
//The type 'R' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>'
{
if (a == null)
return defaultValue;
return func(a);
}
public static Nullable<TResult> GetValueOrDefault<TInput, TResult>(this TInput a, Func<TInput, TResult> func, Nullable<TResult> defaultValue)
where TInput : Attribute
where TResult : struct
//Have to restrict to struct or you get the error:
//The type 'R' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>'
{
if (a == null)
return defaultValue;
return func(a);
}
//In order to constrain to a class without interfering with the overload that has a generic struct constraint
//we need to add a parameter to the signature that is a reference type restricted to a class
public class ClassConstraintHack<T> where T : class { }
//The hack means we have an unused parameter in the signature
//http://msmvps.com/blogs/jon_skeet/archive/2010/11/02/evil-code-overload-resolution-workaround.aspx
public static TResult GetValueOrDefault<TInput, TResult>(this TInput a, Func<TInput, TResult> func, TResult defaultValue, ClassConstraintHack<TResult> ignored = default(ClassConstraintHack<TResult>))
where TInput : Attribute
where TResult : class
{
if (a == null)
return defaultValue;
return func(a);
}
//I don't go so far as to use the inheritance trick decribed in the evil code overload resolution blog,
//just create some overloads that take nullable types - and I will just keep adding overloads for other nullable type
public static bool? GetValueOrDefault<TInput>(this TInput a, Func<TInput, bool?> func, bool? defaultValue)
where TInput : Attribute
{
if (a == null)
return defaultValue;
return func(a);
}
public static int? GetValueOrDefault<TInput>(this TInput a, Func<TInput, int?> func, int? defaultValue)
where TInput : Attribute
{
if (a == null)
return defaultValue;
return func(a);
}
public static T GetAttribute<T>(this PropertyInfo p) where T : Attribute
{
if (p == null)
return null;
return p.GetCustomAttributes(false).OfType<T>().LastOrDefault();
}
public static PropertyInfo GetProperty<T, R>(Expression<Func<T, R>> expression)
{
if (expression == null)
return null;
MemberExpression memberExpression = expression.Body as MemberExpression;
if (memberExpression == null)
return null;
return memberExpression.Member as PropertyInfo;
}
}
.NET allows you to dynamically change structure of Class by implementing System.ComponentModel.ICustomTypeDescriptor. Most serializers support this interface.
// Sample Serialization
foreach(PropertyDescriptor p in TypeDescriptor.GetProperties(obj)){
string name = p.PropertyName;
object value = p.GetValue(obj);
}
Internally TypeDescriptor uses Reflection, but the implementation allows us to override reflection attributes easily.
Here are three steps of implementation,
// Implement System.ComponentModel.ICustomTypeDescriptor Interface on
// your Entity
public class MyEntity: System.ComponentModel.ICustomTypeDescriptor
{
....
// most methods needs only call to default implementation as shown below
System.ComponentModel.AttributeCollection
System.ComponentModel.ICustomTypeDescriptor.GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}
string System.ComponentModel.ICustomTypeDescriptor.GetClassName()
{
return TypeDescriptor.GetClassName(this, true);
}
string System.ComponentModel.ICustomTypeDescriptor.GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}
System.ComponentModel.TypeConverter System.ComponentModel.ICustomTypeDescriptor.GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
System.ComponentModel.EventDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}
System.ComponentModel.PropertyDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(this, true);
}
object System.ComponentModel.ICustomTypeDescriptor.GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}
System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}
System.ComponentModel.PropertyDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
{
return TypeDescriptor.GetProperties(this, attributes, true);
}
object System.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner(System.ComponentModel.PropertyDescriptor pd)
{
return this;
}
// The Only method that needs different implementation is below
System.ComponentModel.PropertyDescriptorCollection
System.ComponentModel.ICustomTypeDescriptor.GetProperties()
{
// ... you are supposed to create new instance of
// PropertyDescriptorCollection with PropertyDescriptor
PropertyDescriptorCollection pdc = new PropertyDescriptorCollection();
foreach(PropertyDescriptor p in TypeDescriptor.GetProperties(this,true)){
// if readonly..
AtomPropertyDescriptor ap = new AtomPropertyDescriptor(p, p.Name);
// or
AtomPropertyDescriptor ap = new AtomPropertyDescriptor(p, p.Name,
true,
new XmlIgnoreAttribute(),
new ScriptIgnoreAttribute(),
new ReadOnlyAttribute());
pdc.Add(ap);
}
return pdc;
}
}
// And here is the AtomPropertyDescriptorClass
public class AtomPropertyDescriptor : PropertyDescriptor
{
PropertyDescriptor desc;
bool? readOnly = null;
public AtomPropertyDescriptor(PropertyDescriptor pd, string name,
bool? readOnly, params Attribute[] attrs) :
base(name, attrs)
{
desc = pd;
this.readOnly = readOnly;
}
public override bool CanResetValue(object component)
{
return desc.CanResetValue(component);
}
public override Type ComponentType
{
get
{
return desc.ComponentType;
}
}
public override object GetValue(object component)
{
return desc.GetValue(component);
}
public override bool IsReadOnly
{
get
{
if (readOnly.HasValue)
return readOnly.Value;
return desc.IsReadOnly;
}
}
public override Type PropertyType
{
get { return desc.PropertyType; }
}
public override void ResetValue(object component)
{
desc.ResetValue(component);
}
public override void SetValue(object component, object value)
{
desc.SetValue(component, value);
}
public override bool ShouldSerializeValue(object component)
{
return desc.ShouldSerializeValue(component);
}
}
I think what you are looking for is a custom Annotation Attribute like this:
<DisableEditAttribute(this.IsProjectStarted)>
Public Property NomInvertebrat As String
public override bool IsValid(bool value)
{
bool result = true;
// Add validation logic here.
if(value)
{
//Compare Current Value Against DB Value.
}
return result;
}
See MSDN: http://msdn.microsoft.com/en-us/library/cc668224(v=vs.98).aspx
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.
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);
}
}
}