This question already has answers here:
Enum "Inheritance"
(17 answers)
Closed 7 years ago.
Is there a way to interface with or inherit the enum of another class? Obviously I can move the enum outside of the class, but I am curious if a reference can be made:
public class deferment
{
public enum test
{
test = 0,
live
}
}
public class defermentLog
{
public enum test1 : deferment:test //this is where I want to reference
{
}
public test1 action()
{
return test1.live;
}
}
In that case, yes, you can.
namespace ConsoleTests
{
using TestAlias = Class1.test;
public class Class1
{
public enum test
{
test,
live
}
}
public class Class2
{
public void x()
{
TestAlias t = TestAlias.live;
}
}
}
Its called a type alias, and its defined like this: using TestAlias= Class1.test;
It should be noted though that you have to define that alias in the file that you use it and it does not copy over to other files, so you have to define it in every one you use it.
Related
This question already has answers here:
Override ToString() is not working in abstract class (.net-core 3.1)
(2 answers)
Closed 2 years ago.
I would like to have a base class that overrides ToString by converting any objects that inherits it to JSON. When running this program, it seems like this in the context of the base object is not the full object, but instead only the base object itself.
Is it possible to refer to the inherited object from the base object?
using System;
using System.Text.Json;
namespace Test
{
public class BaseModel
{
public override string ToString()
{
return JsonSerializer.Serialize(this);
}
}
public class Data : BaseModel
{
public string Name { get; set; }
public int Value { get; set; }
}
class Program
{
static void Main(string[] args)
{
var data = new Data { Name = "Test", Value = 42 };
Console.WriteLine(data);
}
}
}
This happens because JsonSerialize.Serialize<TValue>(TValue, [JsonSerializerOptions]) is a generic method, and, due to type interference, your code is compiled as:
public override string ToString()
{
return JsonSerializer.Serialize<BaseModel>(this);
}
In this case, the solution is to use the non-generic overload JsonSerialize.Serialize(object, Type, [JsonSerializerOptions]) instead:
public override string ToString()
{
return JsonSerializer.Serialize(this, this.GetType());
}
You have to define ToString method in the derived class.
public override string ToString()
{
return JsonSerializer.Serialize(this);
}
This question already has answers here:
Why an inherited interface can't be converted to its base interface in generic context?
(2 answers)
Closed 2 years ago.
I'm trying to write a generic function like the example of the image below.
The idea is to have a method that will receive a generic type that must inherit an abstract class that has a generic configuration which has another abstract class.
public class MainCode
{
public MainCode()
{
Execute<DefaultOptions>();
}
public void Execute<T>() where T : BaseClassOptions<BaseClassConfiguration> { }
}
public class DefaultOptions : BaseClassOptions<DefaultConfiguration> { }
public abstract class BaseClassOptions<T> where T : BaseClassConfiguration
{
public T Config { get; set; }
}
public class DefaultConfiguration : BaseClassConfiguration { }
public abstract class BaseClassConfiguration
{
public string Host { get; set; }
}
But I got the following error:
Could you please help me?
Maybe this will work for you?
public MainCode()
{
Execute<DefaultOptions, DefaultConfiguration>();
}
public void Execute<T, T2>() where T : BaseClassOptions<T2> where T2: BaseClassConfiguration
{ }
The problem is that BaseClassOptions<BaseClassConfiguration> is not the base class for the DefaultOptions, that's why you get this error. It happens because type parameters on generic classes are neither covariant nor contravariant, i.e. there is no inheritance relationship between specializations of the same generic class. If you don't want to use interfaces it may worth to say compiler directly what class to use as a generic parameter with your base type.
This question already has answers here:
Hide a base class method in a generic derived class
(2 answers)
Closed 5 years ago.
I am thinking that there should be a bug in .NET framework as per the specifications "when we refer object directly instead of using the parent reference it should call the hidden member".
For the same scenario I have used generics but it was not supported for more understanding please go through the code and the output for your reference.
Example code be find here.
public class A
{
public A()
{
Console.WriteLine("A ctor called");
Property=111;
}
public int Property { get; set; }
}
public class B
{
public B()
{
Console.WriteLine("B ctor called");
Property=222;
}
public int Property { get; set; }
}
-----With out Generics-----------
public class Caller
{
public virtual int Property { get; set; }
public Caller()
{
Property=4444;
}
public A GetDevice()
{
return new A();
}
}
public class NextCaller:Caller
{
public NextCaller()
{
Property=5464654;
}
public new B GetDevice()
{
return new B();
}
}
-----With Generics-----------
public interface ReferenceType<TType> where TType:Caller
{
TType GetCurrentType();
}
public class Handler<TType>:ReferenceType<TType> where TType:Caller
{
public virtual TType CurrentObj {get;set;}
public virtual TType GetCurrentType()
{
return CurrentObj as TType;
}
public virtual void Show()
{
var type=GetCurrentType();
Console.WriteLine(CurrentObj.Property);
Console.WriteLine(GetCurrentType().GetDevice().Property);
}
}
public class HandlerNext<TType> : Handler<TType> where TType:NextCaller
{
public override TType CurrentObj {get;set;}
public override TType GetCurrentType()
{
return CurrentObj;
}
}
-------Usage Demo-------------------
public class UsageDemo
{
public void Main()
{
//using generics
var handler=new Handler<Caller>();
handler.CurrentObj=new NextCaller();
handler.Show();
var handler1=new HandlerNext<NextCaller>();
handler1.CurrentObj=new NextCaller();
handler1.Show();
//with out using generics
Caller handle=new NextCaller();
Console.WriteLine(handle.GetDevice().Property);
NextCaller handle1=new NextCaller();
Console.WriteLine(handle1.GetDevice().Property);
}
}
Output:-
//using generics
A ctor calledenter code here
111
A ctor called
111
//with out using generics
A ctor called
111
B ctor called
222
Problem here is,
out of those four outputs 2nd out put showing the wrong result because I have deduce the results using generics. If we see result in the output without using the generics it working correctly (refer output 4).
As per the specifications when we refer object directly instead of using the parent reference it should call the hidden member.
The above specification is not working when we use generics.
Because your show method is in the Handler<TType>, it can only access methods and properties of the type Caller because of the :Caller constaint. It cannot access methods from the type NextCaller.
If you create an override for the .Show method in the HandlerNext class with the exact same method body, it will call methods based on the NextCaller type because of the :NextCaller constraint on that class.
This question already has answers here:
How to create instance of inherited in static base method?
(3 answers)
Closed 6 years ago.
I have 2 classes which are derived from an abstract class
abstract class Order
{
public virtual boolean Export()
{
...
}
}
class TradeOrder : Order
{
public override bool Export()
{
//Create a new order
}
}
class LibraryOrder : Order
{
public override bool Export()
{
//Dont create order but Update an existing order
}
}
TradeOrder is created for customertype "Trade" and LibraryOrder is created for customertype "Library".
The customer type will grow in near future.
How do I create instance of the derived class based on the customer type without using if...else or swicth ...case?
The instance of the class will call the export method to either create or update a sales order.
-Alan-
Here is one way to achieve what you want. We can call it "convention over configuration approach" since, obviously, your derived order type names and your enum names have to match.
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var customerType = CustomerType.Library;
var order = (Order)Activator.CreateInstance("ConsoleApplication2", "ConsoleApplication2." + customerType.ToString() + "Order").Unwrap();
}
}
public enum CustomerType
{
Trade,
Library
}
public abstract class Order
{
public virtual void Export() { }
}
public class TradeOrder : Order
{
public override void Export() { }
}
public class LibraryOrder : Order
{
public override void Export() { }
}
}
I suggest have a map of object type name and Type and create instance based on the mapping. The mapping details can be initialized in the code or from external source (Ex. Config file).
enum OrderType
{
TradeOrder,
LibraryOrder
}
Dictionary<OrderType, Type> _orderTypeMap = new Dictionary<OrderType, Type>
{
{ OrderType.LibraryOrder, typeof(LibraryOrder)},
{ OrderType.TradeOrder, typeof(TradeOrder)}
};
Order GetOrderInstance(OrderType orderType)
{
return Activator.CreateInstance(_orderTypeMap[orderType]) as Order;
}
This question already has answers here:
method without access modifier
(8 answers)
Default Class Accessibility in C#
(4 answers)
Closed 8 years ago.
If we do not specify Public/Private/Protected, what will it be?
Is there something known as a private class?
1: that depends on whether the class is nested or not. A top level class defaults to internal. A nested class defaults to private.
class TopLevelClass {
class PrivateClass {
}
}
2: yes, but only for nested classes:
class TopLevelClass {
private class ExplicitlyPrivateClass {
}
class ImplicitlyPrivateClass {
}
}
If you don't specify Public/Private/Protected for a main class it will be internal, for a nested class the default access specifier will be private.
private class exists. You can access a private class only if it is declared inside another class. Means it is private to the parent class as
class example //which is default interal
{
private class ex
{
}
class ex1 //default private
{
}
}
1) If no modifier is specified, the visibility will depend on the situation where it is omitted; the topic is discussed in this question.
2) In the following code, InnerClass is private in OuterClass.
namespace ClassTest
{
class OuterClass
{
private class InnerClass
{
}
OuterClass()
{
InnerClass Test = new InnerClass();
}
}
class Program
{
static void Main(string[] args)
{
OuterClass TestOne = new OuterClass();
InnerClass TestTwo = new InnerClass(); // does not compile
}
}
}
What are the Default Access Modifiers in C#?
and there is a private class but in my opinion its pointless