Interface default property value not being overwritten in .NET6 Winforms app, works in .NET6 console app - interface

Using .NET 5 and C# 9.
I am trying to reduce code written to eliminate mistakes down the road. This question may be related to this one.
I have a Interface defined and I want to have the boolean values default to false:
public interface IMenuActionInterface
{
public bool CanConnect => false;
public bool CanDisconnect => false;
public bool CanHome => false;
public bool CanPoll => false;
public bool CanRunAutomatically => false;
public bool CanRunManually => false;
public bool CanPurge => false;
}
Then in each Interface implementation I want to just define the properties that are true:
internal class NotConnected : IMenuActionInterface
{
public bool CanConnect => true;
}
I have a variable defined as IMenuActionInterface and assign that variable various implementations of IMenuActionInterface:
private IMenuActionInterface _robotState;
_robotState = robot.SetOptions(Trigger.Connect)
//Code for SetOptions:
public IMenuActionInterface SetOptions(Trigger trigger)
{
switch (trigger)
{
case Trigger.Connect:
return new Connected();
case Trigger.Disconnect:
return new NotConnected();
case Trigger.Home:
return new Homed();
case Trigger.StartRunning:
return new Running();
case Trigger.StopRunning:
return new Homed();
case Trigger.StartPurging:
return new Purging();
case Trigger.StopPurging:
return new Homed();
default:
throw new ArgumentOutOfRangeException(nameof(trigger), trigger, null);
}
}
In the case where I return a new NotConnected() instance of _robotState.CanConnect returns false. The debugger seems to display both the default value AND the overridden class value.
What is happening here?
I want to define all default properties in my interface and then just define properties in the implementation of the interface that need to have a different value - how?
EDIT The code actually returns the default false.
Edit 2
NotConnected class looks like this:
internal class NotConnected : IMenuActionInterface
{
public bool CanConnect => true;
}
Homed class looks like this:
internal class Homed : IMenuActionInterface
{
internal bool CanDisconnect => true;
internal bool CanHome => true;
internal bool CanPoll => true;
}
If I assign 'test = new Homed()' the value of test.CanDisconnect should return true. It does not. The output of my simplified code:
IMenuActionInterface test = new NotConnected();
Debug.WriteLine(test.CanDisconnect);
test = new Homed();
Debug.WriteLine(test.CanDisconnect);
is:
False
False
Adding even more data to this I edited a dotnetfiddle to reflect my issue and it worked as expected (False, True). I also created a .NET6 console app in visual studio and it works fine as well (False, True). I then created a winforms app with .net6 and this pattern does not work. I get:
False
False
rather then the expected:
False
True
There is definitely different behaviour between .NET6 Console app and .NET6 winform app.

I found the issue....
I looked very carefully at my code and found that the keyword has to be public on the properties in both the Interface and the class that implements the interface.
If both are set to public then all is good:
In fact it seems the compiler is very particular with how the property is defined. These both work:
interface IMenuActionInterface
{
bool CanConnect => false;
bool CanDisconnect => false;
}
public class Testing : IMenuActionInterface
{
}
public class DoubleTesting : IMenuActionInterface
{
public bool CanDisconnect => true;
}
-and-
interface IMenuActionInterface
{
bool CanConnect => false;
public bool CanDisconnect => false;
}
public class Testing : IMenuActionInterface
{
}
public class DoubleTesting : IMenuActionInterface
{
public bool CanDisconnect => true;
}
It seems that if I use any other combination of modifier then it does not like it.

Related

Dialog interaction requests using IObservable

I'm using reactive programming to build an MVVM app and am trying to figure out how my view model can raise a question and wait for a dialog to prompt the user for an answer.
For example, when the user clicks a Rename button I want a dialog to pop up that allows the user to change the text. My approach is for the view model to expose an IObservable<string> property. Code-behind in the View listens for emitted values and might display a UWP ContentDialog. If the user changes the text and clicks OK, code in that dialog would call ReportResult(string newText) on view model. I've got some code below to show how it works. Two questions:
Is this a reasonable approach for collecting information from the user?
Also, I've got two subtly different approaches for building this and don't know which is better.
interface IServiceRequest<TSource, TResult> : ISubject<TResult, TSource> { }
// Requests for information are just 'passed through' to listeners, if any.
class ServiceRequestA<TSource, TResult> : IServiceRequest<TSource, TResult>
{
IObservable<TSource> _requests;
Subject<TResult> _results = new Subject<TResult>();
public ServiceRequestA(IObservable<TSource> requests)
{
_requests = requests;
}
public IObservable<TResult> Results => _results;
public void OnCompleted() => _results.OnCompleted();
public void OnError(Exception error) => _results.OnError(error);
public void OnNext(TResult value) => _results.OnNext(value);
public IDisposable Subscribe(IObserver<TSource> observer) => _requests.Subscribe(observer);
}
// Requests for information are 'parked' inside the class even if there are no listeners
// This happens when InitiateRequest is called. Alternately, this class could implement
// IObserver<TSource>.
class ServiceRequestB<TSource, TResult> : IServiceRequest<TSource, TResult>
{
Subject<TSource> _requests = new Subject<TSource>();
Subject<TResult> _results = new Subject<TResult>();
public void InitiateRequest(TSource request) => _requests.OnNext(request);
public IObservable<TResult> Results => _results;
public void OnCompleted() => _results.OnCompleted();
public void OnError(Exception error) => _results.OnError(error);
public void OnNext(TResult value) => _results.OnNext(value);
public IDisposable Subscribe(IObserver<TSource> observer) => _requests.Subscribe(observer);
}
class MyViewModel
{
ServiceRequestA<string, int> _serviceA;
ServiceRequestB<string, int> _serviceB;
public MyViewModel()
{
IObservable<string> _words = new string[] { "apple", "banana" }.ToObservable();
_serviceA = new ServiceRequestA<string, int>(_words);
_serviceA
.Results
.Subscribe(i => Console.WriteLine($"The word is {i} characters long."));
WordSizeServiceRequest = _serviceA;
// Alternate approach using the other service implementation
_serviceB = new ServiceRequestB<string, int>();
IDisposable sub = _words.Subscribe(i => _serviceB.InitiateRequest(i)); // should dispose later
_serviceB
.Results
.Subscribe(i => Console.WriteLine($"The word is {i} characters long."));
WordSizeServiceRequest = _serviceB;
}
public IServiceRequest<string, int> WordSizeServiceRequest { get; set; }
// Code outside the view model, probably in the View code-behind, would do this:
// WordSizeServiceRequest.Select(w => w.Length).Subscribe(WordSizeServiceRequest);
}
Based on comments from Lee Campbell, here is a different approach. Maybe he'll like it better? I'm actually not sure how to build the IRenameDialog. Before it was just a bit of code-behind in the View.
public interface IRenameDialog
{
void StartRenameProcess(string original);
IObservable<string> CommitResult { get; }
}
public class SomeViewModel
{
ObservableCommand _rename = new ObservableCommand();
BehaviorSubject<string> _name = new BehaviorSubject<string>("");
public SomeViewModel(IRenameDialog renameDialog,string originalName)
{
_name.OnNext(originalName);
_rename = new ObservableCommand();
var whenClickRenameDisplayDialog =
_rename
.WithLatestFrom(_name, (_, n) => n)
.Subscribe(n => renameDialog.StartRenameProcess(n));
var whenRenameCompletesPrintIt =
renameDialog
.CommitResult
.Subscribe(n =>
{
_name.OnNext(n);
Console.WriteLine($"The new name is {n}");
};
var behaviors = new CompositeDisposable(whenClickRenameDisplayDialog, whenRenameCompletesPrintIt);
}
public ICommand RenameCommand => _rename;
}
Hmm.
The first block of code looks like a re-implementation of IObservable<T>, actually I think event worse ISubject<T>, so that raises alarm bells.
Then the MyViewModel class does other things like pass IObservable<string> as a parameter (Why?), create subscriptions (side effects) in the constructor, and expose a Service as a public property. You also metion having code in your view code behind, which is often a code-smell in MVVM too.
I would suggest reading up on MVVM (solved problem for 10yrs) and havnig a look at how other Client applications use Rx/Reactive programming with MVVM (solved problem for ~6yrs)
Lee shamed me into coming up with a better solution. The first and best turned out to be very simple. I pass into the constructor one of these:
public interface IConfirmationDialog
{
Task<bool> Show(string message);
}
Inside my view model, I can do something like this...
IConfirmationDialog dialog = null; // provided by constructor
_deleteCommand.Subscribe(async _ =>
{
var result = await dialog.Show("Want to delete?");
if (result==true)
{
// delete the file
}
});
Building a ConfirmationDialog wasn't hard. I just create one of these in the part of my code that creates view models and assigns them to views.
public class ConfirmationDialogHandler : IConfirmationDialog
{
public async Task<bool> Show(string message)
{
var dialog = new ConfirmationDialog(); // Is subclass of ContentDialog
dialog.Message = message;
var result = await dialog.ShowAsync();
return (result == ContentDialogResult.Primary);
}
}
So the solution above is pretty clean; dependencies my view model needs are provided in the constructor. Another approach similar to what Prism and ReactiveUI do is one where the ViewModel is constructed without the dependency it needs. Instead there is a bit of code-behind in the view to fill in that dependency. I don't need to have multiple handlers, so I just have this:
public interface IInteractionHandler<TInput, TOutput>
{
void SetHandler(Func<TInput, TOutput> handler);
void RemoveHandler();
}
public class InteractionBroker<TInput, TOutput> : IInteractionHandler<TInput, TOutput>
{
Func<TInput, TOutput> _handler;
public TOutput GetResponse(TInput input)
{
if (_handler == null) throw new InvalidOperationException("No handler has been defined.");
return _handler(input);
}
public void RemoveHandler() => _handler = null;
public void SetHandler(Func<TInput, TOutput> handler) => _handler = handler ?? throw new ArgumentNullException();
}
And then my ViewModel exposes a property like this:
public IInteractionHandler<string,Task<bool>> Delete { get; }
And handles the delete command like this:
_deleteCommand.Subscribe(async _ =>
{
bool shouldDelete = await _deleteInteractionBroker.GetResponse("some file name");
if (shouldDelete)
{
// delete the file
}
});

How to use ReactiveCommand canexecute

I'm new in WPF, implementing application using reactiveUI.
I have one button and added command handler for it.
want to call the method only when canExecute is true.
in viewmodel, i have defined it
public bool canExecute
{
get { return _canExecute;}
set { _canExecute = value;}
}
Bind()
{
AddRecord = new ReactiveCommand(_canExecute);
AddRecord .Subscribe(x =>
{
AddR()
}
}
void AddR()
{
}
but its not working. how to convert it in to System.IObservable?
As #jomtois mentions, you need to fix your declaration of CanExecute:
bool canExecute;
public bool CanExecute {
get { return canExecute; }
set { this.RaiseAndSetIfChanged(ref canExecute, value); }
}
Then, you can write:
AddRecord = new ReactiveCommand(this.WhenAnyValue(x => x.CanExecute));
Why go to all this effort? This makes it so that when CanExecute changes, ReactiveCommand automatically enables / disables. However, this design is pretty imperative, I wouldn't create a CanExecute boolean, I'd think about how I can combine properties related to my ViewModel that have a semantic meaning.

Autofac PropertiesAutowired - Is it possible to ignore a one or more properties?

Despite the advice to pass dependencies through the constructor I've found that the development cost of having parameterless constructors and then autowiring all of the properties on everything is significantly less and makes the application much easier to develop out and maintain. However sometimes (on a view model for example) I have a property that is registered with the container, but that I don't want to populate at construction (for example the selected item bound to a container).
Is there any way to tell the container to ignore certain properties when it autowires the rest?
At the moment I'm just resetting the properties marked with an attribute in the on activated event a la:
public static IRegistrationBuilder<TLimit, ScanningActivatorData, TRegistrationStyle>
PropertiesAutowiredExtended<TLimit, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, ScanningActivatorData, TRegistrationStyle> builder)
{
builder.ActivatorData.ConfigurationActions.Add(
(type, innerBuilder) =>
{
var parameter = Expression.Parameter(typeof(object));
var cast = Expression.Convert(parameter, type);
var assignments = type.GetProperties()
.Where(candidate => candidate.HasAttribute<NotAutowiredAttribute>())
.Select(property => new { Property = property, Expression = Expression.Property(cast, property) })
.Select(data => Expression.Assign(data.Expression, Expression.Default(data.Property.PropertyType)))
.Cast<Expression>()
.ToArray();
if (assignments.Any())
{
var #action = Expression
.Lambda<Action<object>>(Expression.Block(assignments), parameter)
.Compile();
innerBuilder.OnActivated(e =>
{
e.Context.InjectUnsetProperties(e.Instance);
#action(e.Instance);
});
}
else
{
innerBuilder.OnActivated(e => e.Context.InjectUnsetProperties(e.Instance));
}
});
return builder;
}
Is there a better way to do this?
Not sure that this is a better one, but you can go from another side, register only needed properties via WithProperty syntax. Pros is that Autofac doesn't resolve unnecessary services. Here's a working example:
public class MyClass
{
public MyDependency MyDependency { get; set; }
public MyDependency MyExcludeDependency { get; set; }
}
public class MyDependency {}
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<MyDependency>();
builder.RegisterType<MyClass>().WithPropertiesAutowiredExcept("MyExcludeDependency");
using (var container = builder.Build())
{
var myClass = container.Resolve<MyClass>();
Console.WriteLine(myClass.MyDependency == null);
Console.WriteLine(myClass.MyExcludeDependency == null);
}
}
}
public static class PropertiesAutowiredExtensions
{
// Extension that registers only needed properties
// Filters by property name for simplicity
public static IRegistrationBuilder<TLimit, TReflectionActivatorData, TRegistrationStyle>
WithPropertiesAutowiredExcept<TLimit, TReflectionActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TReflectionActivatorData, TRegistrationStyle> registrationBuilder,
params string[] propertiesNames)
where TReflectionActivatorData : ReflectionActivatorData
{
var type = ((IServiceWithType)registrationBuilder.RegistrationData.Services.Single()).ServiceType;
foreach (var property in type
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(pi => pi.CanWrite && !propertiesNames.Contains(pi.Name)))
{
// There's no additional checks like in PropertiesAutowired for simplicity
// You can add them from Autofac.Core.Activators.Reflection.AutowiringPropertyInjector.InjectProperties
var localProperty = property;
registrationBuilder.WithProperty(
new ResolvedParameter(
(pi, c) =>
{
PropertyInfo prop;
return pi.TryGetDeclaringProperty(out prop) &&
prop.Name == localProperty.Name;
},
(pi, c) => c.Resolve(localProperty.PropertyType)));
}
return registrationBuilder;
}
// From Autofac.Util.ReflectionExtensions
public static bool TryGetDeclaringProperty(this ParameterInfo pi, out PropertyInfo prop)
{
var mi = pi.Member as MethodInfo;
if (mi != null && mi.IsSpecialName && mi.Name.StartsWith("set_", StringComparison.Ordinal)
&& mi.DeclaringType != null)
{
prop = mi.DeclaringType.GetProperty(mi.Name.Substring(4));
return true;
}
prop = null;
return false;
}
}

How can I dynamically make entity properties read-only?

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

Where did Option[T] come from in Scala?

I'm still a noob in Scala development but I have found the Option[T] concept really awesome, specially the pattern matching when used with Some and None. I am even implementing it so some extent in a C# project I'm working on at the moment, but as there is no pattern matching in there is isn't really that awesome.
The real question is, where is the theory behind this object? is it something specific from Scala? Funcional languages? Where can I find more about it?
Most of the time I was thinking that it comes from the Haskell, and has a name of Maybe monad
But after a little research, I've found that there was some references on option types in SML papers, as #ShiDoiSi said. Moreover, it has the same semantics (Some/None) that Scala has.
The elderest paper I was able to find is that (circa '89) (see footnote on the 6th page)
You don't need pattern-matching to use Option. I have written it in C# for you below. Note that the Fold function takes care of anything that would otherwise be pattern-matched.
Pattern-matching is generally discouraged in favour of higher-level combinators. For example, if your particular function can be written using Select you would use it rather than Fold (which is equivalent to pattern-matching). Otherwise, assuming side-effect free code (and therefore, equational reasoning), you would essentially be re-implementing existing code. This holds for all languages, not just Scala or C#.
using System;
using System.Collections;
using System.Collections.Generic;
namespace Example {
/// <summary>
/// An immutable list with a maximum length of 1.
/// </summary>
/// <typeparam name="A">The element type held by this homogenous structure.</typeparam>
/// <remarks>This data type is also used in place of a nullable type.</remarks>
public struct Option<A> : IEnumerable<A> {
private readonly bool e;
private readonly A a;
private Option(bool e, A a) {
this.e = e;
this.a = a;
}
public bool IsEmpty {
get {
return e;
}
}
public bool IsNotEmpty{
get {
return !e;
}
}
public X Fold<X>(Func<A, X> some, Func<X> empty) {
return IsEmpty ? empty() : some(a);
}
public void ForEach(Action<A> a) {
foreach(A x in this) {
a(x);
}
}
public Option<A> Where(Func<A, bool> p) {
var t = this;
return Fold(a => p(a) ? t : Empty, () => Empty);
}
public A ValueOr(Func<A> or) {
return IsEmpty ? or() : a;
}
public Option<A> OrElse(Func<Option<A>> o) {
return IsEmpty ? o() : this;
}
public bool All(Func<A, bool> f) {
return IsEmpty || f(a);
}
public bool Any(Func<A, bool> f) {
return !IsEmpty && f(a);
}
private A Value {
get {
if(e)
throw new Exception("Value on empty Option");
else
return a;
}
}
private class OptionEnumerator : IEnumerator<A> {
private bool z = true;
private readonly Option<A> o;
private Option<A> a;
internal OptionEnumerator(Option<A> o) {
this.o = o;
}
public void Dispose() {}
public void Reset() {
z = true;
}
public bool MoveNext() {
if(z) {
a = o;
z = false;
} else
a = Option<A>.Empty;
return !a.IsEmpty;
}
A IEnumerator<A>.Current {
get {
return o.Value;
}
}
public object Current {
get {
return o.Value;
}
}
}
private OptionEnumerator Enumerate() {
return new OptionEnumerator(this);
}
IEnumerator<A> IEnumerable<A>.GetEnumerator() {
return Enumerate();
}
IEnumerator IEnumerable.GetEnumerator() {
return Enumerate();
}
public static Option<A> Empty {
get {
return new Option<A>(true, default(A));
}
}
public static Option<A> Some(A t) {
return new Option<A>(false, t);
}
}
}
Wikipedia is your friend: http://en.wikipedia.org/wiki/Option_type
Unfortunately it doesn't give any dates, but I'd bet that it's ML-origin predates Haskell's Maybe.