I'm reading the code in here. I find that private ITreeModel _model; in TreeList.cs:
namespace Aga.Controls.Tree
{
public class TreeList: ListView
{
#region Properties
//...
private ITreeModel _model;
public ITreeModel Model
{
//...
}
//...
}
}
and the ITreeModel is a interface in ITreeModel.cs:
namespace Aga.Controls.Tree
{
public interface ITreeModel
{
/// <summary>
/// Get list of children of the specified parent
/// </summary>
IEnumerable GetChildren(object parent);
/// <summary>
/// returns wheather specified parent has any children or not.
/// </summary>
bool HasChildren(object parent);
}
}
the _model is a instantiated object?
Edited:
TreeList.cs:
namespace Aga.Controls.Tree
{
public class TreeList: ListView
{
#region Properties
/// <summary>
/// Internal collection of rows representing visible nodes, actually displayed in the ListView
/// </summary>
internal ObservableCollectionAdv<TreeNode> Rows
{
get;
private set;
}
private ITreeModel _model;
public ITreeModel Model
{
get { return _model; }
set
{
if (_model != value)
{
_model = value;
_root.Children.Clear();
Rows.Clear();
CreateChildrenNodes(_root);
}
}
}
private TreeNode _root;
internal TreeNode Root
{
get { return _root; }
}
//....
}
}
}
Edited2:
Somewhere:
public partial class RegistrySample : UserControl
{
public RegistrySample()
{
InitializeComponent();
_tree.Model = new RegistryModel();
}
}
class RegistryModel : ITreeModel
Of course you can do this, but underlying object must implement this Interface. So you can do something like
ITreeModel _model = new TreeModel();
Where
public class TreeModel:ITreeModel
{
...
}
You can never instantiate an interface in C# directly, but yes you can instantiate a subclass implementing that interface. For example:
interface IShape
{
//Method Signature
void area(int r);
}
public class Circle : IShape
{
//method Implementation
void area(int r)
{
float area;
area = 3.14 * r * r;
Console.WriteLine("The area of the circle is: {0}",area);
}
}
public class Shapes
{
public static void Main() {
//Uncommenting the following line will cause compiler error as the
// line tries to create an instance of interface.
// interface i = new IShape();
// We can have references of interface type.
IShape i = new Circle();
i.area(10);
}
}
It's implemented somewhere else in the code. If you call _model.GetType().ToString() you will see it is not just an interface.
But to answer your question correctly, YES, an interface can be instantiated. Some of you may think "no it can't", but it can be done (with some COM hacks):
class Foo : IFoo
{
readonly string name;
public Foo(string name)
{
this.name = name;
}
string IFoo.Message
{
get
{
return "Hello from " + name;
}
}
}
// these attributes make it work
// (the guid is purely random)
[ComImport, CoClass(typeof(Foo))]
[Guid("d60908eb-fd5a-4d3c-9392-8646fcd1edce")]
interface IFoo
{
string Message {get;}
}
//and then somewhere else:
IFoo foo = new IFoo(); //no errors!
Here is my source.
That _model should contain an instance of a class that implements that ITreeModel interface (or it's null).
From Interfaces (C# Programming Guide)
An interface can't be instantiated directly. Its members are
implemented by any class or struct that implements the interface.
No _model is an interface reference to instance of a class object which implements ITreeModel
_model is a member of TreeList and that means that you can create an instance of a class and then it will contain an instance of some class. for example
_model = new TreeModel();
will make _model contain an instance
but you cannot do
_model = new ITreeModel();
because ITreeModel is and interface and you cannot create an instance of an interface
Related
I have the class structure like below:
public interface IBinder<T>
where T : Control
{
T Control { get; }
}
public class ButtonBinder : IBinder<Button>
{
public ButtonBinder(Button control)
{
Control = control ?? throw new ArgumentNullException(nameof(control));
}
public Button Control { get; private set; }
}
Create instances of that Binder I want with help of a factory method like this:
public void Main()
{
// This line works.
var binder = RegisterBinder<ButtonBinder, Button>(new Button());
// But I want use type inference like this:
var binder2 = RegisterBinder<ButtonBinder>(new Button());
}
/// <summary>
/// My pseudo-factory.
/// </summary>
public T_Binder RegisterBinder<T_Binder, T_Control>(T_Control control)
where T_Binder : IBinder<T_Control>
where T_Control : Control
{
return (T_Binder)Activator.CreateInstance(typeof(T_Binder), control);
}
Because the class 'ButtonBinder' declares the generic control type 'Button' the Compiler should be able to infer it.
How I can tell the compiler that I want to use type inference?
Thank you.
Unfortunately C# cannot infer only one of multiple generic parameters.
However, if you do not mind capturing the inferable type in an intermediate class you can do something like this:
public class Factory
{
public void Main()
{
// This line works.
var binder = RegisterBinder<ButtonBinder, Button>(new Button());
// Now only T_Binder is needed
var binder2 = ForControl(new Button()).RegisterBinder<ButtonBinder>();
}
private BinderRegistration<T_Control> ForControl<T_Control>(T_Control control) where T_Control : Control
{
return new BinderRegistration<T_Control>(control);
}
/// <summary>
/// My pseudo-factory.
/// </summary>
public T_Binder RegisterBinder<T_Binder, T_Control>(T_Control control)
where T_Binder : IBinder<T_Control>
where T_Control : Control
{
return (T_Binder)Activator.CreateInstance(typeof(T_Binder), control);
}
}
internal class BinderRegistration<T_Control>
where T_Control : Control
{
private readonly Control _control;
public BinderRegistration(Control control)
{
_control = control;
}
public T_Binder RegisterBinder<T_Binder>()
where T_Binder : IBinder<T_Control>
{
return (T_Binder)Activator.CreateInstance(typeof(T_Binder), _control);
}
}
I am maintaining one object(Parent) in my MainWindow class. That Parent Object is being passed to another object(objMyClass). Now If I update Parent Object in mainwindow, it is not reflecting it in objMyClass object. Below is the code.
using System.Windows;
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public Parent objParent;
public MyClass objMyClass;
public MainWindow()
{
InitializeComponent();
objParent = new Parent();
objMyClass = new MyClass(objParent);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if ((bool)checkPWB.IsChecked)
objParent = new Child1();
else
objParent = new Child2();
objParent.Display();
objMyClass.par.Display();
}
}
public class MyClass
{
public Parent par;
public MyClass(Parent p)
{
par = p;
}
}
public class Parent
{
public virtual void Display()
{
MessageBox.Show("I am Parent");
}
}
public class Child1 : Parent
{
public override void Display()
{
MessageBox.Show("I am Child1");
}
}
public class Child2 : Parent
{
public override void Display()
{
MessageBox.Show("I am Child2");
}
}
}
When I click the button, I am creating a new object (Child1) and assigning to my parent object which doesn't reflect it in ObjectMyClass.
Any help on this is appreciated.
To refer to the same field you can use Func<Parent> that would return current value of the filed:
public class MyClass
{
private Func<Parent> getParent = null;
public Parent par => getParent();
public MyClass(Func<Parent> getParent)
{
this.getParent = getParent;
}
}
and construct your class as
objMyClass = new MyClass(() => objParent);
This way instead of having its own reference to Parent object that contains copy of the original value of the parameter (as in code in the question) this MyClass will always return current value of objParent field and indeed reflect changes to that field.
Alternatively you can just change par property directly instead of changing objParent.
If I have this hierarchy of classes:
Class Shape
{
public bool closedPath;
}
class Circle : Shape
{
}
class Line: Shape
{
}
Here I know that all circles are closed paths.
How to set the value of closedPath field to these defaults without the need to assign its value when instantiating an object of that said class?
You can declare your closedPath as a virtual read-only property and then define it in descendant classes:
class Shape
{
public virtual bool closedPath {get;}
}
class Circle : Shape
{
public override bool closedPath => true;
}
class Line: Shape
{
public override bool closedPath => false;
}
Things you might also consider are:
changing your Shape class to the abstract class or to the IShape interface.
You can also achieve the same result with a read-only field and initialize that field in the constructor.
You can pass a value to the base constructor:
class Shape
{
public bool closedPath;
public Shape(bool closedPath)
{
this.closedPath = closedPath;
}
}
class Circle : Shape
{
public Circle()
: base(true)
{
}
}
class Line : Shape
{
public Line()
: base(false)
{
}
}
Then you'd get:
void SomeMethod()
{
Shape circle = new Circle();
Console.WriteLine(circle.closedPath); // True
Shape line = new Line();
Console.WriteLine(line.closedPath); // False
}
I wish to implement suspend and resume binding in silverlight using a flag while doing heavy operation in a binding scenario.
My problem is in the existing project uses heavy binding drawing mechanismm.
Using UpdateTrigger() in silverlight we could achieve manual triggering of binding.
But its a huge product. Its not possible to update and find the locations for manual triggering of binding and so on and change the project.
So we planned to use Microsoft Unity to quickly fix by suspend and resume binding using a flag on heavy load drawing operation. This may be quick fix for the current performance issue while drawing binding objects.
I wish to check a bool flag before setting value to the properties for different Type?
I googled so much and tired to find Interception before property setter. But not found a way. Still fighting. This is my exact requirement.
Anybody to help?
Added the sample code trying,
//Empty Interface may be used in interface interception, not sure.
public interface ISetter
{
}
//Implementation of ISetter, this type needs to be intercepted while setting the FirstName //property
public class Man : ISetter
{
private string firstName;
public Man()
{
}
[NotifyHandler] //Expected: this handler should be called when FirstName property set
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
}
public class NotifyHandler : ICallHandler
{
public Boolean Before { get; set; }
public Boolean After { get; set; }
public String Message { get; set; }
int ICallHandler.Order { get; set; }
IMethodReturn ICallHandler.Invoke(IMethodInvocation input,
GetNextHandlerDelegate getNext)
{
if (this.Before == true)
{
Debug.WriteLine(this.Message);
}
IMethodReturn result = getNext()(input, getNext);
if (result.Exception != null)
{
Debug.WriteLine(result.Exception.Message);
}
else
{
if (this.After == true)
{
Debug.WriteLine(this.Message);
}
}
return (result);
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property
| AttributeTargets.Method)]
Public class NotifyHandlerAttribute : HandlerAttribute
{
public NotifyHandlerAttribute()
{
}
public override ICallHandler CreateHandler(IUnityContainer ignored)
{
return new NotifyHandler();
}
}
public abstract class HandlerAttribute : Attribute
{
/// Derived classes implement this method. When called, it creates a
/// new call handler as specified in the attribute configuration.
/// The parameter "container" specifies the IUnityContainer
/// to use when creating handlers, if necessary.
/// returns a new call handler object.
public abstract ICallHandler CreateHandler(IUnityContainer container);
private int executionorder;
/// <summary>
/// Gets or sets the order in which the handler will be executed.
/// </summary>
public int Order
{
get { return this.executionorder; }
set { this.executionorder = value; }
}
}
//Interception registered in the application start up
private void Application_Startup(object sender, StartupEventArgs e)
{
IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<Man>().Configure<Interception>();
var m1 =container.Resolve<Man>();
m1.FirstName = "test";
Man m = new Man();
m.FirstName = "fine";
}
In above both the FirstName setter property does not call the NotifyHandler.
This is essentially what I want to do:
public abstract class Uniform<T>
{
public readonly int Location;
private T _variable;
public virtual T Variable
{
get { return _variable; }
}
}
public class UniformMatrix4 : Uniform<Matrix4>
{
public override Matrix4 Variable
{
set
{
_variable = value;
GL.UniformMatrix4(Location, false, ref _variable);
}
}
}
The getter for Variable will be the same across all derived classes, but the setter needs to be different.
In fact... I'd prefer not to have derived classes at all (it's only one function call that will differ for each type) but I can't think of how else to do it.
Edit: If it wasn't clear what the problem I'm having is, I'm getting a syntax error:
'UniformMatrix4.Variable.set': cannot override because 'Uniform.Variable' does not have an overridable set accessor
And I'm not sure how to create an "overridable set accessor"... virtual and abstract don't seem to be allowed on the setter.
It's not possible to do this in C#, but as a workaround you could do this. It would involve calling an abstract setter function which could be overridden by derived classes, while leaving the standard get intact. Would this work?
public abstract class Uniform<T>
{
public readonly int Location;
protected T _variable;
public T Variable
{
get { return _variable; }
set { SetVariable(value); }
}
protected abstract void SetVariable(T value);
}
public class UniformMatrix4 : Uniform<Matrix4>
{
public override void SetVariable(Matrix4x4 value)
{
_variable = value;
GL.UniformMatrix4(Location, false, ref _variable);
}
}
You will need to do this:
public abstract class Uniform<T>
{
public readonly int Location;
public virtual T Variable
{
get; set;
}
}
public class UniformMatrix4 : Uniform<Matrix4>
{
public override Matrix4 Variable
{
get
{
return base.Variable;
}
set
{
base.Variable = value;
GL.UniformMatrix4(Location, false, ref value);
}
}
}
As I understand, the behaviour will be the expected.
Hope it helps.
It is not possible to do this in C#. You have to add a setter to the base class, and make it throw an "Invalid Operation" exception.