How to access properties of generic base class's parameter in C#? - c#

I have a common class PopupDialog which has properties such as bool IsBackDismissEnabled. This is used to denote whether pressing back button will dismiss the dialog.
I am using Xamarin.CommunityToolkit Popup for showing a popup dialog.
Here's my PopupDialog.cs
public class PopupDialog
{
public bool IsBackDismissEnabled { get; set; }
}
Here's my Dialog Implementation
using Xamarin.CommunityToolkit.UI.Views;
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ForgotPasswordDialog : Popup<PopupDialog>
{
public ForgotPasswordDialog()
{
InitializeComponent();
// I want to access IsBackDismissEnabled here
// something like base.IsBackDismissEnabled = true;
}
}
I want to access PopupDialog's IsBackDismissEnabled from the derived class of Popup<PopupDialog> how can it be done?
In short, I have a class which is specified as a parameter to a generic class. And that generic class is derived in a class from which I want to access properties of previous class that is specified as a parameter to the generic class.

I've never seen anyone attempt to do what you are attempting. I'm not even sure it makes logical sense. Please explain what you are trying to do: Why do you want PopupDialog to be a generic parameter?
Consider making it a parameter on Popup's constructor, and save it in a property or field:
public class Popup
{
public Popup(ISomeInterface myParam)
{
this.MyParam = myParam;
}
public ISomeInterface MyParam;
}
public class ForgotPasswordDialog : Popup
{
public ForgotPasswordDialog() : base(new PopupDialog())
{
}
void SomeMethod()
{
// Access MyParam
... this.MyParam.IsBackDismissEnabled ...
}
}
public interface ISomeInterface
{
bool IsBackDismissEnabled { get; set; }
}
public class PopupDialog : ISomeInterface
{
public bool IsBackDismissEnabled { get; set; }
...
}
/// Usage
var myVariable = new ForgotPasswordDialog();
... myVariable.MyParam.IsBackDismissEnabled ...
To be useful, you'll want to specify an interface or base class that MyParam has. Here I show ISomeInterface. This might instead be some base class of PopupDialog.

Related

How to downcast this to the base class?

I have this class hierarchy:
public abstract class AClass : SomeFrameworkClass {
[WorkOnThisProperty(With.Some.Context)]
private MyObject MyProperty { get; set; }
public override void OnSomethingHappened() {
ExternalFramework.WorkOn(this);
}
}
public class BClass : AClass {
// ... Snip ...
}
ExternalFramework is operating on this: an instance of BClass but i need it to operate on this as an instance of AClass because ExternalFramework only works on the type of the object passed in and does not go up the inheritance hierarchy. How can i downcast this into AClass so ExternalFramework can actually detect MyProperty?
I've tried casting this to object and then to AClass, and casting it directly to AClass but as the cast is unnecessary it doesn't seem to run. What can i do about this?
EDIT: ExternalFramework is Cheeseknife. I am trying to inject a couple views into a base fragment class that has all the reusable logic while child fragment classes implement some specific behaviour tuning.
The problem is that all private members of a class can only be accessed inside of the same class.
With this code:
class A { private string Property { get; set; } }
class B : A { public string Proxy => Property; }
We'll get compilation error because class B cannot access private property from class A, but if change keyword to protected :
class A { protected string Property { get; set; } }
It should work.

Passing a control as a generic parameter type and inheriting from it

I have a number of custom controls that extend from existing Windows Forms controls as well as one or more interfaces designed my myself. The implementation of these interfaces is virtually identical within each custom control, so I would have repeating code such as the following:
public class CustomTextBox : TextBox, ISomeInterface
{
// Implementations of interface members
...
}
public class CustomButton : Button, ISomeInterface
{
// Implementations of interface members
...
}
Ideally I would like to be able to do something similar to the following:
public abstract class BaseCustomControl<C> : C, ISomeInterface where C : Control
{
// Implementations of interface members
}
public class CustomTextBox : BaseCustomControl<TextBox>
{
// Implementations of interface members
...
}
public class CustomButton : BaseCustomControl<Button>
{
// Implementations of interface members
...
}
This way, my identical implementations would be removed and consolidated into a single base class to reduce repeating code. Unfortunately, this isn't possible; are there any suitable alternatives I can use?
Since C# doesn't support multiple inheritance, you're going to have to use composition to get the behavior you want.
Define a pair of interfaces; one is the "real" interface, and the other does nothing more than provide an instance of the first:
public interface ISomeInterface
{
string Foo { get; }
void Bar();
}
public interface ISomeInterfaceControl
{
ISomeInterface SomeInterface { get; }
}
Then create an implementation of the "real" interface:
public class SomeInterfaceImpl : ISomeInterface
{
private Control _control;
public string Foo { get; private set; }
public void Bar()
{
}
public SomeInterfaceImpl(Control control)
{
_control = control;
}
}
And modify your controls to implement the "wrapper" interface by returning an instance of the "real" interface implementation:
public class CustomTextBox : TextBox, ISomeInterfaceControl
{
public ISomeInterface SomeInterface { get; private set; }
public CustomTextBox()
{
this.SomeInterface = new SomeInterfaceImpl(this);
}
}
Now all of the logic is contained inside the "SomeInterfaceImpl" class, but you can access that logic for any of your custom controls as follows:
CustomTextBox customTextBox = new CustomTextBox();
customTextBox.SomeInterface.Bar();
If the behavior for your custom controls needs to vary, you can introduce a parallel inheritance hierarchy for ISomeInterface:
public class TextBoxSomeInterface : SomeInterfaceImpl
{
public TextBoxSomeInterface(CustomTextBox textBox)
: base(textBox)
{
}
}
public class ButtomSomeInterface : SomeInterfaceImpl
{
public ButtomSomeInterface(CustomButton button)
: base(button)
{
}
}
And use it like this:
public class CustomTextBox : TextBox, ISomeInterfaceControl
{
public ISomeInterface SomeInterface { get; private set; }
public CustomTextBox()
{
this.SomeInterface = new TextBoxSomeInterface(this);
}
}
You could look into extension methods.
As an example
// This would be your interface method
public static bool IsHigh(this Control mySelf) {
return mySelf.Height > 100;
}
If your classes then extend Control (or one of it's sub-classes) you can simply call the method like this:
CustomTextBox tb = new CustomTextBox();
if (tb.IsHigh()) ...

Get an interface property value in a generic class

I have this interface
public interface IMyInterface
{
IEnumerable<MyParamInfo> Params { get; }
}
where
MyParamInfo is
public class MyParamInfo
{
public MyParamInfo (string name)
{
Name= name;
}
public string Name { get; private set; }
}
also
this class
public class MyClass:IMyInterface
{
//properties
....
public IEnumerable<MyParamInfo> Params
{
get
{
return new List<MyParamInfo> { new MyParamInfo("Param1")};
}
}
}
and this Form
public partial class MyForm<T> : Form where T:Class,IMyInterface
{
...
}
with this code
MyForm<MyClass> frm = new MyForm<MyClass>();
How can I access to Params Property of MyClass in frm object?
If you also require that the T type parameter of MyForm have a parameterless constructor, you can instantiate an instance of T and then use the interface property at will.
On the definition of MyForm, add the new() generic constraint
public partial class MyForm<T> : Form where T : Class, IMyInterface, new()
Then in some method of MyForm<T>, you can use:
(new T()).Params;
You can read about all the constraints on type parameters in C# here.
It seems like what you really want is interfaces that could specify static methods (so-called static interfaces). Such a construct does not exist in C#.

How to automatically copy a property declaration to base class

I have a property A in all subclasses of base class Base.
How can I generate an abstract property definition of property A into base class Base?
I know ReSharper's refactoring Pull Members Up, but that moves the property to base class.
I need an abstract property in base class and a overriding properties in all sub classes. Is there a refactoring in Visual Studio or in ReSharper that can do it automatically for me?
There is a checkbox "Make abstract" for that in ReSharper Pull Members Up dialog :
I'm not sure Resharper can move up and create an abstraction as you want automatically, but you can atleast define it manually like this
In abstract class:
public abstract double A
{
get;
}
In Sub class:
public override double A
{
get
{
return 3.141;
}
}
It might be a clearner design to define a new Interface (or use an existing one) and define the property in the interface. That way, your existing subclasses won't have to use override.
public interface IInterface {
string MyProperty { get; }
}
public class Class : IInterface {
public string MyProperty { get; set; }
}
public abstract class AbstractClass {
public abstract string Value { get; }
}
public class ConcreteClass : AbstractClass {
private string m_Value;
public override string Value {
get { return m_Value; }
}
public void SetValue(string value) {
m_Value = value;
}
}
I hope this will be helpful to you.

Changing the Type of a inherited property (to a inherited type)

using C# I have a class which contains among other meta information the root node of a directed graph. Let's call this the Container-Class. This container can appear in two different modes, Editor-Mode and Configurator-Mode. Depending on the mode, the root-node is of a different type NodeEdit or NodeConfig, both inheriting from the same subclass.
public abstract class NodeBase
{
string Name { get; set; }
...
}
public class NodeEdit : NodeBase ...
public class NodeConfig : NodeBase ...
For the container, I also create a base class and inherit from it:
public abstract class ContainerBase
{
NodeBase Root { get; set; }
...
}
When creating the classes for Editor- and Configuratorcontainer by inheriting from ContainerBase, I want to become the type of the Root - property the specific (inherited from NodeBase) type like:
public class ContainerEditor : ContainerBase
{
NodeEditor Root { get; set; }
...
}
But I cannot change the type of a property defined in ContainerBase. Is there a way to solve this problem? I can use the BaseNode-type, and add an element of NodeEditor like
ContainerEditorInstance.Root = new NodeEditor();
because the type NodeEditor is inherited from type BaseEditor, but in the Container-Editor class, I want to explicitly only allow the type of the Root-property to be NodeEditor.
I could check this in the setter and reject all nodes but those of type NodeEditor, but I'd like to have the property be of the specific type, so I can detect wrong assignments at compile-time.
Thanks in advance,
Frank
Use generics:
public abstract class ContainerBase<T> where T:NodeBase
{
T Root { get; set; }
...
}
public class ContainerEditor : ContainerBase<NodeEditor>
{
...
}
You can redeclare it:
public class ContainerEditor : ContainerBase
{
public NodeEditor Root {
get { return (NodeEditor)base.Root; }
set { base.Root = value; }
}
...
}
You can make the container base generic:
public abstract class ContainerBase<TRoot> where TRoot : NodeBase
{
TRoot Root { get; set; }
...
}
In the derived class you specify the type:
public class ContainerEditor : ContainerBase<NodeEditor>
{
...
}
I suppose a good solution here will be Generics. So you'd write something like this:
public class ContainerEditor<T>:ContainerBase
{
T Root {get;set;}
}

Categories