I am using initiazling property in a class
and i want to run a validation method after it fully initialized.
i cant use the constructor for obvious reasons. is there a way to do that in some kind of Class initialized event ?
var t = new Foo
{
foo = "";
}
class Foo
{
public string foo {get; set;}
...
public bool validate {get ; set;}
private void validation()
{
if(foo == "")
validate = false;
if ...
}
}
(Note: for clarity, I renamed the property to Bar, in order to easily distinguish it from the type Foo)
If the Bar property must be valid upon construction, why are you not requiring it in the constructor? Why are you allowing the construction of invalid objects?
class Foo
{
public Foo(string bar) {
if(!IsValidBar(bar))
throw new ArgumentException("bar is not valid.", "bar");
this.Bar = bar;
}
public string Bar {get; set;}
private bool IsValidBar(string bar)
{
// blah blah
}
}
Alternatively, if you can construct an instance of Foo without the value of the Bar property, but you don't want to allow setting Bar to an invalid value, you can validate this in the setter:
class Foo
{
private string bar;
public string Bar
{
get { return bar; }
set
{
if(!IsValidBar(value))
throw new ArgumentException("bar is not valid.", "value");
bar = value;
}
}
private bool IsValidBar(string bar)
{
// blah blah
}
}
You can add verification logic to properties. Verify if class initialized after property assigned and raise static event if initialization completed. You can get reference to instance by casting event sender to Foo.
public string Foo
{ get { return _foo; }
set
{
_foo = value;
if (IsInitialized)
OnClassInitialized();
}
}
public static event EventHandler ClassInitialized;
private OnClassInitialized()
{
if (ClassInitialized != null)
ClassInitialized(this, EventArgs.Empty);
}
Usage:
Foo.ClassInitialized += (sender, e) =>
{
Foo foo = sender as Foo;
...
};
One approach is an interface designed for validation purposes; IValidation for instance. IValidation could then contain a Validate method. Classes which need to provide the behavior can now do so in a manageable way.
This prevents bloating within the constructor which IMHO is bad design.
You can use Aspect Oriented Programming like postsharp. http://www.postsharp.org/. But you lose on performance.
You can avoid using proprty initializers, and just move all that code to the constructor, using optional parameters if there are lots of properties. That way, you'll get kind-of property initializer constructor, and yet still be able to validate the class after the initialization is done. Something like this:
class Foo
{
public string Foo {get; set;}
public string Bar {get; set;}
public bool IsValid {get ; set;}
private void Validation()
{
if(foo == "")
IsValid = false;
if ...
}
public void Foo(string foo = string.Empty, string bar = string.Empty)
{
Foo = foo;
Bar = bar;
Validation();
}
}
.....
var t = new Foo (Foo = "SomeString");
The downside is that this is relatively new C# 4 syntax.
If you can't use c# 4, you could use the property accessors to enable validation, e.g. like:
public string Foo
{
get { return foo; }
set
{
foo = value;
Validation();
}
}
but this will evaluate the validity on each set, and might be slow if you set a lot of properties at once. You could also use the get accessor on combination with some lazy loading, something like this:
public bool IsValid
{
get
{
if (!isValidated)
Validation();
return isValid;
}
private set { isValid = value; }
}
public string Foo
{
get { return foo; }
set
{
foo = value;
isValidated := false;
}
}
Related
Assume I have some class that represents a container. That container holds some public properties with get and set modifiers.
What I want is to implement some mechanism that will enable access and disable access to these properties reference at runtime.
For example, when some boolean flag is true, you can access these properties. That means that:
SomeClass.Property1;
Will not generate an exception and will return the object.
However, when it is false, the above line of code will throw an exception.
It is of course possible to be done when using some boolean key, and checking it at the gateway to every property.
My question is, is it possible to implement such mechanism that will enfoce these limitations for all the properties in the class, without the need to assert these conditions within every access to these properties.
Thanks for helping.
It looks like null object pattern might helps.
Simple code that shows how it can be used in your case. Not exactly the same as you want but it doesn't need to assert conditions with every access to object's properties and methods.
Entities:
abstract class AbstractEntity
{
public abstract void DoSomething();
public abstract void DoSomethingElse();
public abstract int Property { get; set; }
}
class RealEntity : AbstractEntity
{
public override void DoSomething()
{
Console.WriteLine("Something");
}
public override void DoSomethingElse()
{
Console.WriteLine("Something else");
}
public override int Property { get; set; }
}
class NullEntity : AbstractEntity
{
public override void DoSomething()
{
// do nothing or throw exception
}
public override void DoSomethingElse()
{
// do nothing or throw exception
}
public override int Property
{
get { throw new Exception(); }
set { throw new Exception(); }
}
}
Simple example of AccessContainer:
class AccessContainer
{
private RealEntity _entity = new RealEntity();
private NullEntity _nullEntity = new NullEntity();
private bool _access = true;
public AbstractEntity Entity
{
get => _access ? (AbstractEntity) _entity : (AbstractEntity) _nullEntity;
}
public void OpenAccess()
{
_access = true;
}
public void DenyAccess()
{
_access = false;
}
}
Usage:
var container = new AccessContainer();
container.Entity.DoSomething(); // prints something
var prop = container.Entity.Property; // access to property
container.DenyAccess();
container.Entity.DoSomething(); // do nothing
container.OpenAccess();
container.Entity.DoSomething(); // prints something again
container.DenyAccess();
var prop2 = container.Entity.Property; // exception
What you are asking for doesn't natively exist, you're going to have to write some sort of wrapping functionality to test whether accessibility is granted.
public interface IAccessOwner {
bool Accessible { get; }
}
[DebuggerDisplay("Accessible: {Accessible,nq} - Value: {ToString()}")]
[DebuggerTypeProxy(typeof(RestrictedObject<>.DebuggerProxy))]
public class RestrictedObject<T> {
private readonly IAccessOwner _owner;
private T _value;
public RestrictedObject(IAccessOwner owner, T initialValue)
: this(owner) {
_value = initialValue;
}
public RestrictedObject(IAccessOwner owner) {
_owner = owner ?? throw new ArgumentNullException(nameof(owner));
}
public T Value {
get {
ThrowIfInaccessible();
return _value;
}
set {
ThrowIfInaccessible();
_value = value;
}
}
public bool Accessible => _owner.Accessible;
public override string ToString() {
if (!Accessible)
return "<Inaccessible>"; // ToString should never throw
if (_value is { } val)
return val.ToString();
return "<null>";
}
private void ThrowIfInaccessible() {
if(!Accessible)
throw new InvalidOperationException("Not accessible!");
}
// explicit operator to cast directly to value
public static explicit operator T(RestrictedObject<T> ro) {
ro.ThrowIfInaccessible();
return ro.Value;
}
private sealed class DebuggerProxy {
public bool Accessible { get; }
public T Value { get; }
public DebuggerProxy(RestrictedObject<T> ro) {
bool acc = Accessible = ro.Accessible;
if (acc)
Value = ro._value;
}
}
}
You can then use properties of this type in your class:
public class MyClass : IAccessOwner {
private readonly RestrictedObject<int> _prop1;
private readonly RestrictedObject<string> _prop2;
public MyClass(int someVal) {
_prop1 = new RestrictedObject<int>(this, someVal);
_prop2 = new RestrictedObject<string>(this);
Accessible = true;
}
public bool Accessible { get; private set; }
// you determine how you want to toggle the above property.
// Exposing it publicly defeats the purpose of all of this,
// but for demo purposes only:
public void DenyAccess() {
Accessible = false;
}
public void AllowAccess() {
Accessible = true;
}
// these properties will throw exceptions if the owner
// (this object) is not currently accessible.
public int Prop1 {
get => _prop1.Value;
set => _prop1.Value = value;
}
public string Prop2 {
get => _prop2.Value;
set => _prop2.Value = value;
}
// alternatively return the wrapper itself
// allowing you to control the accessibility
// even after returning the object
public RestrictedObject<string> AltProp2 => _prop2;
}
You would then use it like the following (obviously exceptions will halt the execution, handling has been elided):
var mc = new MyClass(3);
Console.WriteLine(mc.Prop1); // prints 3
Console.WriteLine(mc.Prop2); // prints null
var temp = mc.AltProp2; // use the wrapper directly
mc.Prop2 = "Hello";
Console.WriteLine(mc.Prop2); // prints Hello
Console.WriteLine(temp.Value); // prints Hello
Console.WriteLine((string)temp); // explicit operator, prints Hello
mc.DenyAccess();
mc.Prop1 = 33; // throws!
Console.WriteLine(mc.Prop1); // throws!
Console.WriteLine(mc.Prop2); // throws!
Console.WriteLine(temp.Value); // throws!
Console.WriteLine((string)temp); // explicit operator, throws!
Console.WriteLine(temp); // prints "<Inaccessible>"
mc.AllowAccess();
string temp3 = (string)temp; // "Hello", explicit operator works again
mc.Prop1 = 22; // as do our setters
mc.Prop2 = "Goodbye";
if (temp.Accessible) {
Console.WriteLine(temp); // "Goodbye"
}
The only thing that won't throw an exception is the override of ToString on the RestrictedObject type itself since you should never throw from ToString. Instead we just return <Inaccessible>.
We've also changed how the RestrictedObject<T> is displayed in a debugger via the DebuggerTypeProxyAttribute. If someone tries to inspect the object's properties they will see the Accessible property and only if true will the wrapped object's Value appear. Otherwise, default(T) will be displayed (null for reference types, 0 for integral types and false for bool). Furthermore, through use of the DebuggerDisplayAttribute we've customized the display of the collapsed version of our object such that it shows the Accessible property alongside our customized ToString.
Note that this still has the drawback that if someone retrieves the inner/wrapped object and accessibility has later been denied, they still have the object. There's nothing you are going to be able to do to really guard against that case. You must also realize (and accept) that anyone using reflection could alter or access the state of the object if they really wanted to.
I will also note that this violates normal C# practices, which typically dictate that properties should not throw exceptions. Microsoft's own guidelines say as much, though they use the term "Avoid" rather than "Do Not". The framework itself is guilty of violating this "rule". If you're going to violate the principle of least surprise, at the very least have the courtesy to document this behavior for consumers of your API.
How do I use the propfull tab tab gadget in visual studio?
Class Foo
{
public int regirsterR0
{
get { return R0; }
set { R0 = value; }
}
}
How would I use the get and set methods from another class? Let's say this method is in a class called foo. How would I use the get and set from foo in goo?
Class Goo
{
Foo g= new Foo();
g.regirsterR0.Get?????
}
First, thats called a snippet (and there are a bunch of others!). This one creates a full property (MSDN) definition.
To answer your question; you just use it as if it were a field:
var test = g.Register0; //invokes get
g.Register0 = 2; //invokes set
get and set are nice method abstractions that are called when the associated property is accessed or assigned to.
Note that you don't even need the snippet; you could have used an auto-property:
public int RegisterR0 { get; set; } //Properties are PascalCase!
Get and Set is not a value or method. Actually they are property like a control mechanism. (encapsulation principle)
for ex:
var variable = g.Register0; // so it is get property. // like a var variable = 5;
g.Register0 = 5; // so it is set property.
Look msdn explaining.
You just forgot create method. :-)
class Foo
{
private int regirsterR0;
public int RegirsterR0
{
get { return regirsterR0; }
set { regirsterR0 = value; }
}
}
class Goo
{
Foo g = new Foo();
void myMethod()
{
// Set Property
g.RegirsterR0 = 10;
// Get property
int _myProperty = g.RegirsterR0;
}
}
If you want initialize new object of class Foo with Value you can:
class Foo
{
private int regirsterR0;
public int RegirsterR0
{
get { return regirsterR0; }
set { regirsterR0 = value; }
}
}
class Goo
{
Foo g = new Foo() { RegirsterR0 = 10 };
void myMethod()
{
Console.WriteLine("My Value is: {0}", g.RegirsterR0);
}
}
But usualy you don't need use propfull. Will be fine if you use prop + 2xTAB. Example:
class Foo
{
public int RegirsterR0 { get; set; }
}
class Goo
{
Foo g = new Foo() { RegirsterR0 = 10 };
void myMethod()
{
Console.WriteLine("My Value is: {0}", g.RegirsterR0);
}
}
Wrok the same and easer to read.
Here is my code
private MyClass _someProperty
[Dependency]
public MyClass SomeProperty
{
get{
if(_someProperty == null)
_someProperty = new MyClass()
return (MyClass)_someProperty
}
}
This works good, but I'm directed like "No need to add "get" property for [Dependency]"
I'm not clear with this [Dependency] attribute. When I looked into other code, it is written as
[Dependency]
public AnotherClass MyNewClass
{
get; set;
}
When I tried the above for MyClass, it didn't work. It threw the Property is NULL
Can anybody tell me what is the use of the [Dependency] and whether there is an alternate way for MyClass code and why it is coming as "NULL" for that?
This has nothing to do with the DependencyAttribute. The latter case is simply a auto-generated property. If you like to use this syntax you have to fill in the value within your constructor.
public class MyClass
{
public MyClass()
{
SomeProperty = new AnotherClass();
}
public AnotherClass SomeProperty { get; set; }
}
Be aware that you in this case you can't perform any checks within the getter or setter. So if you need any nullity checks or like to raise an event within the setter, you have to implement the getter and setter on yourself.
public class MyClass
{
private AnotherClass _SomeProperty;
public MyClass()
{
_SomeProperty = new AnotherClass();
}
public AnotherClass SomeProperty
{
get { return _SomeProperty; }
set
{
if(value == null)
throw new ArgumentNullException("SomeProperty");
if(value != _SomeProperty)
{
_SomeProperty = value;
// ToDo: Implement RaiseEvent() and declare event.
RaiseEvent(MyEvent);
}
}
}
}
I'm trying to customize a property wherein if I click the elipses button [...] a new dialog form will be displayed. Unfortunately, the form won't show. Can you please check the below code and advise where did I go wrong?
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System;
namespace Test01
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
void MainFormLoad(object sender, EventArgs e)
{
Form form = new Form();
propertyGrid1.SelectedObject = new MyType();
}
}
class MyType
{
private string bar;
[Editor(typeof(FooEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))]
public string Bar
{
get { return bar; }
set { bar = value; }
}
}
[Editor(typeof(FooEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))]
class Foo
{
private string bar;
public string Bar
{
get { return bar; }
set { bar = value; }
}
}
class FooEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value)
{
IWindowsFormsEditorService svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
Foo foo = value as Foo;
if (svc != null && foo != null)
{
using (FooForm form = new FooForm())
{
form.Value = foo.Bar;
if (svc.ShowDialog(form) == DialogResult.OK)
{
foo.Bar = form.Value; // update object
}
}
}
return value; // can also replace the wrapper object here
}
}
class FooForm : Form
{
private TextBox textbox;
private Button okButton;
public FooForm()
{
textbox = new TextBox();
Controls.Add(textbox);
okButton = new Button();
okButton.Text = "OK";
okButton.Dock = DockStyle.Bottom;
okButton.DialogResult = DialogResult.OK;
Controls.Add(okButton);
}
public string Value
{
get { return textbox.Text; }
set { textbox.Text = value; }
}
}
}
Your editor works with the Foo type (if value isn't Foo then it won't show the dialog) but you create an instance of MyType, it contains one property Bar of type string then it can't be edited by your FooEditor.
To try how your code works you should change the property Bar from string to Foo:
class MyType
{
private Foo bar = new Foo();
[Editor(typeof(FooEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))]
public Foo Bar
{
get { return bar; }
set { bar = value; }
}
}
EXAMPLES
Let's see two examples. In the first one you edit the property where the Attribute has been applied (then your editor changes the value of the property itself):
This is the class you'll edit in the PropertyGrid, I removed the Foo class because useless for this example:
class MyType
{
private string bar;
[Editor(typeof(MyStringEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))]
public string Bar
{
get { return bar; }
set { bar = value; }
}
}
This is the editor that will edit your Bar property. Actually it works with any property of type string:
class MyStringEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
var svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
string text = value as string;
if (svc != null && text != null)
{
using (FooForm form = new FooForm())
{
form.Value = text;
if (svc.ShowDialog(form) == DialogResult.OK)
{
return form.Value;
}
}
}
return value;
}
}
Now another example, the editor doesn't change the property value itself but the value of a property of that property (editor is applied to property MyType.Bar (of type Foo) but it changes the value of the property Value of Foo.
Let's introduce again a complex type for your Bar property:
class Foo
{
private string _value;
private object _tag; // Unused in this example
public string Value
{
get { return _value; }
set { _value = value; }
}
public object Tag
{
get { return _tag; }
set { _value = _tag; }
}
}
Change the MyType class to publish one property of the complex type we wrote, note that the EditorAttribute now uses a new editor specific for the Foo type:
class MyType
{
private Foo bar = new Foo();
[Editor(typeof(FooEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))]
public Foo Bar
{
get { return bar; }
set { bar = value; }
}
}
Finally we write the editor for the Foo type. Please note that this editor will change only the value of the property Foo.Value, the other property exposed by Foo won't be touched:
class FooEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
var svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
Foo foo = value as Foo;
if (svc != null && foo != null)
{
using (FooForm form = new FooForm())
{
form.Value = foo.Value;
if (svc.ShowDialog(form) == DialogResult.OK)
{
// Updates the value of the property Value
// of the property we're editing.
foo.Value = form.Value;
}
}
}
// In this case we simply return the original property
// value, the property itself hasn't been changed because
// we updated the value of an inner property
return value;
}
}
Last notes: in the if block of svc.ShowDialog() we have the update value from the Form, the property Bar (where the editor is applied) won't be changed but we'll update the Value property of the Foo instance it contains. Roughly equivalent to write something like this:
MyType myType = new MyType();
myType.Bar.Value = form.Value;
If we just return a new value for the property (like in the previous example) the old value of Tag property will be lost, something like this:
MyType myType = new MyType();
Foo foo = new Foo();
foo.Value = form.Value;
myType.Bar = foo;
Can you see the difference? Anyway it's going to be too more a tutorial than an answer...
Please note that examples are untested, I just wrote them here, I just would like to expose the concept more than to provide a surely working example.
REFERENCES
Here you can find a short list of useful resources:
A comprehensive example about how UITypeEditor works
Main source for PropertyDescriptor documentation is always MSDN but here you can find a pretty short example.
If you just need to localize property names you may take a look to this entry here on SO.
The business object is Foo.cs
What if Foo`s properties run custom logic? Would it then not a bad idea to create Foo objects which could change the data inside the Foo object and it returns values I do not expect?!
public class FooBuilder
{
private string bar = "defaultBar";
private string baz = "defaultBaz";
private string bling = "defaultBling";
public FooBuilder Bar(string value)
{
bar = value;
return this;
}
public FooBuilder Baz(string value)
{
baz = value;
return this;
}
public FooBuilder Bling(string value)
{
bling = value;
return this;
}
public Foo Build()
{
return new Foo {Bar = bar, Baz = baz, Bling = bling};
}
}
If I understand what you are asking...
It is ok for proprties to execute some code more than setting a backing fields. However if you set a property to one value and then use the getter and discover that it has returned a different value to what you set then that is unexpected. So either this should be avoided within properties or use methods that provide descriptive meaning as to the behaviour/data change.
so this IMO is bad
var foo = new Foo();
foo.Bar = "hello bar";
string bar = foo.Bar;
Console.WriteLine(bar); // if this does not print "hello bar" then it is bad/unexpected