I have a class that I've defined, and I have a number of child classes derived from it. The parent class has an enum (let's call it 'Barf'). Each descendant ALSO has an enum with the same name but not the same values. What I'm trying to figure out how to do is write a method in the ancestor class that gets the version of Barf for the actual class of the instantiated object. So if I create an instance of Ancestor, I'd like to have this method process the entries for Ancestor.Barf . If I create an instance of one of the child classes of Ancestor, I'd like to have the method process Childx.Barf values.
Obviously this is going to be a Reflection solution, but my reflection skills are pretty sparse. Any help?
Just for the fun of it, here is a possible approach:
public class Ancestor {
public enum Caffeine {
Tea,
Coffee
}
public void ProcessValues() {
var type = GetType();
var nestedEnums = from t in type.GetNestedTypes()
where t.IsEnum
select t;
var nestedEnum = nestedEnums.Single();
foreach(var val in Enum.GetValues(nestedEnum)) {
Console.WriteLine("Drinking {0}", val);
}
}
}
public class Descendant : Ancestor {
public new enum Caffeine {
Jolt,
RedBull
}
}
// The following prints:
// Drinking Jolt
// Drinking RedBull
Ancestor x = new Descendant();
x.ProcessValues();
Of course, you could achieve the same thing using polymorphism:
public class Ancestor {
public enum Caffeine {
Tea,
Coffee
}
protected virtual Type GetNestedEnum() {
return typeof(Ancestor.Caffeine);
}
public void ProcessValues() {
var nestedEnum = GetNestedEnum();
foreach(var val in Enum.GetValues(nestedEnum)) {
Console.WriteLine("Drinking {0}", val);
}
}
}
public class Descendant : Ancestor {
public new enum Caffeine {
Jolt,
RedBull
}
protected override Type GetNestedEnum() {
return typeof(Descendant.Caffeine);
}
}
As Justin Morgan has pointed out however, having the need for such a construct may be an indication of an underlying design issue in your code.
Related
How can i use class instance in another class like a pointer in C++ to class instance functions?
Example:
class A {
constructor()
{
this.block = [];
}
method()
{
return this.blocks.length;
}
}
another class:
class B {
constructor(instance)
{
this.instance = instance;
}
method()
{
this.instance.method(); // here i'm getting cannot get length of undefined
}
}
If i'm trying to to like that i'm getting problems to call it
You can try this. Here, when creating B class's instance I give into it an A class's instance as argument. Then inside B we can call A instance's methods, and access its properties.
Also, as #ViaTech posted you can use static methods to access them without needing to initialize an object of the class. That is what static methods is. Refer Static Methods
class B {
constructor(instance)
{
this.instance = instance;
}
method()
{
this.instance.method();
}
}
class A {
constructor()
{
}
method()
{
console.log("A's method");
}
}
var a = new A();
var b = new B(a);
b.method(); // A's method
You can easily do this in JS by calling a static method like so:
class A {
static write(){ //static method
console.log("Called write from A");
}
}
class B {
doIt(){
A.write();
}
}
let b = new B();
b.doIt();
Option 2, you instantiate the class in the constructor of the other like so:
class A {
write(){
console.log("Non-static write() called from class A");
}
}
class B {
constructor() {
this.a = new A();
}
doIt(){
this.a.write();
}
}
let b = new B();
b.doIt();
There are a few ways:
I accidentally switched between PHP and Javascript, but the principles are the same for both)
Use static functions:
Normally, you have a this in the class. Say you have this code:
class Car {
let color;
public function setColor(newColor){ this.color = newColor;}
}
let car = new Car();
car->setColor('green')`
The setColor function's this refers to that car. You can make let anotherCar = new Car(), then when you do anotherCar->setColor('red') you only change that car, not the first one. Simplistic: You can create multiple instances.
If you do not need that, but need the class once, you can make it static. A simple way to explain would be "you have a collection of seperate functions, just put into a wrapping class (which doesn't do a lot really)". For instance, you might have some sanatizing methods:
class Sanitize {
static function makeHtmlSave(input){
return doYourMagicHere(input);
}
static function removeXssCode(input){
return doMoreMagicHere(input);
}
}
This way, you can reuse it multiple times. If you want to use it, you do Sanitize::makeHtmlSave(someCode) where you need it. There isn't a Sanitize thing, it's just a wrapper to access the frunctions inside it.
Use extend:
You can extend a class. Say you have a generic class Vehicle, which has some properties (eg a motor, numberWeels, color) and you can extend that with more specific classes:
class Vehicle {
let color;
public function setColor(newColor){ this.color = newColor}
}
class Car extends Vehicle {
let hasAirco = false;
public function hasAirco(newValue){ this.hasAirco = newValue};
}
If you do let car = new Car(), you get a Car object, that extends/enlarges/complements the Vehicle class, so you can use both its (public) functions. Internally, Car can use the functions of Vehicle too.
Just pass it
class One {
// some stuff
}
class Two{
let otherObject;
construct(givenObject){
this.otherObject = givenObject;
}
}
You can now do this let a = new One(); let b = new Two(a);. You can not use the functions of One inside Two, but you can still use a->doSomething(). This solution feels like the easiest, but it almost never is. Classes/objects are tricky stuff, but I've rarely uses this solutions. There are use cases, but often it's a bad smell indicator.
In java we can write thead-safe singletons using double Checked Locking & volatile:
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance(String arg) {
Singleton localInstance = instance;
if (localInstance == null) {
synchronized (Singleton.class) {
localInstance = instance;
if (localInstance == null) {
instance = localInstance = new Singleton(arg);
}
}
}
return localInstance;
}
}
How we can write it in kotlin?
About object
object A {
object B {}
object C {}
init {
C.hashCode()
}
}
I used kotlin decompiler to get that
public final class A {
public static final A INSTANCE;
private A() {
INSTANCE = (A)this;
A.C.INSTANCE.hashCode();
}
static {
new A();
}
public static final class B {
public static final A.B INSTANCE;
private B() {
INSTANCE = (A.B)this;
}
static {
new A.B();
}
}
public static final class C {
public static final A.C INSTANCE;
private C() {
INSTANCE = (A.C)this;
}
static {
new A.C();
}
}
}
All of object have constructor invoke in static block. Based on it, we can think that it's not lazy.
Сlose to the right answer.
class Singleton {
companion object {
val instance: Singleton by lazy(LazyThreadSafetyMode.PUBLICATION) { Singleton() }
}
}
Decompiled:
public static final class Companion {
// $FF: synthetic field
private static final KProperty[] $$delegatedProperties = new KProperty[]{(KProperty)Reflection.property1(new PropertyReference1Impl(Reflection.getOrCreateKotlinClass(Singleton.Companion.class), "instance", "getInstance()Lru/example/project/tech/Singleton;"))};
#NotNull
public final Singleton getInstance() {
Lazy var1 = Singleton.instance$delegate;
KProperty var3 = $$delegatedProperties[0];
return (Singleton)var1.getValue();
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
I hope Kotlin developers will make non reflection implementation in future...
Kotlin has an equivalent of your Java code, but more safe. Your double lock check is not recommended even for Java. In Java you should use an inner class on the static which is also explained in Initialization-on-demand holder idiom.
But that's Java. In Kotlin, simply use an object (and optionally a lazy delegate):
object Singletons {
val something: OfMyType by lazy() { ... }
val somethingLazyButLessSo: OtherType = OtherType()
val moreLazies: FancyType by lazy() { ... }
}
You can then access any member variable:
// Singletons is lazy instantiated now, then something is lazy instantiated after.
val thing = Singletons.something // This is Doubly Lazy!
// this one is already loaded due to previous line
val eager = Singletons.somethingLazyButLessSo
// and Singletons.moreLazies isn't loaded yet until first access...
Kotlin intentionally avoids the confusion people have with singletons in Java. And avoids the "wrong versions" of this pattern -- of which there are many. It instead provides the simpler and the safest form of singletons.
Given the use of lazy(), if you have other members each would individually be lazy. And since they are initialized in the lambda passed to lazy() you can do things that you were asking about for about customizing the constructor, and for each member property.
As a result you have lazy loading of Singletons object (on first access of instance), and then lazier loading of something (on first access of member), and complete flexibility in object construction.
See also:
lazy() function
Lazy thread safe mode options
Object declarations
As a side note, look at object registry type libraries for Kotlin that are similar to dependency injection, giving you singletons with injection options:
Injekt - I'm the author
Kodein - Very similar and good
Object declaration is exactly for this purpose:
object Singleton {
//singleton members
}
It is lazy and thread-safe, it initializes upon first call, much as Java's static initializers.
You can declare an object at top level or inside a class or another object.
For more info about working with objects from Java, please refer to this answer.
As to the parameter, if you want to achieve exactly the same semantics (first call to getInstance takes its argument to initialize the singleton, following calls just return the instance, dropping the arguments), I would suggest this construct:
private object SingletonInit { //invisible outside the file
lateinit var arg0: String
}
object Singleton {
val arg0: String = SingletonInit.arg0
}
fun Singleton(arg0: String): Singleton { //mimic a constructor, if you want
synchronized(SingletonInit) {
SingletonInit.arg0 = arg0
return Singleton
}
}
The main flaw of this solution is that it requires the singleton to be defined in a separate file to hide the object SingletonInit, and you cannot reference Singleton directly until it's initialized.
Also, see a similar question about providing arguments to a singleton.
I recently wrote an article on that topic.
TL;DR Here's the solution I came up to:
1) Create a SingletonHolder class. You only have to write it once:
open class SingletonHolder<out T, in A>(creator: (A) -> T) {
private var creator: ((A) -> T)? = creator
#Volatile private var instance: T? = null
fun getInstance(arg: A): T {
val i = instance
if (i != null) {
return i
}
return synchronized(this) {
val i2 = instance
if (i2 != null) {
i2
} else {
val created = creator!!(arg)
instance = created
creator = null
created
}
}
}
}
2) Use it like this in your singletons:
class MySingleton private constructor(arg: ArgumentType) {
init {
// Init using argument
}
companion object : SingletonHolder<MySingleton, ArgumentType>(::MySingleton)
}
The singleton initialization will be lazy and thread-safe.
In the programming language Haxe, I have multiple different 'item' classes that should be able to give a value when provided with some arguments. These functions should have no contact with actual object instances, but still belong in these class, thus, they should be static.
However, I want to be able to pass in the 'Apple' or 'Mango' class (not an instance) and call a static method. Normally I would create a typedef if I wanted to be able to access method, however what do I do when the method is static?
eg -
class food
+eat()
+throw()
Apple extends food
+eat()
+(static) getFatLevels (p:Person)
Mango extends food
+eat()
+throw()
+(static) getFatLevels (p:Person)
...
function chooseBestFood () {
for (food in Foods){
if (food.getFatLevels(person) < lowest){
return (food);
}
}
}
Typedefs work fine, but you need to use class notation to avoid "is method but should be var" errors:
typedef HasMagic = {
function magic():Void;
}
class Foo {
public static function magic()
{
return 314;
}
}
class Bar {
public static function magic()
{
return 42;
}
}
class Test {
static function main()
{
var items:Array<HasMagic> = [Foo, Bar];
for (i in items)
trace(i.magic());
}
}
(on try haxe)
You might also need to restrict DCE in some cases.
I don't follow how you would use typedefs here. However, if you know your child classes will all implement this static method, you can do the following in a non-type-safe way:
class Food
{
static function main() {
var myFoodClass:Class<Food> = Apple;
var method = Reflect.field(myFoodClass, "getFatLevels");
trace(Reflect.callMethod(myFoodClass, method, []));
}
}
class Apple extends Food
{
public static function getFatLevels():Int
{
return 5;
}
}
Consider the following existing classes which uses MEF to compose Consumer.
public interface IProducer
{
void Produce();
}
[Export(typeof(IProducer))]
public class Producer : IProducer
{
public Producer()
{
// perform some initialization
}
public void Produce()
{
// produce something
}
}
public class Consumer
{
[Import]
public IProducer Producer
{
get;
set;
}
[ImportingConstructor]
public Consumer(IProducer producer)
{
Producer = producer;
}
public void DoSomething()
{
// do something
Producer.Produce();
}
}
However, the creation of Producer has become complex enough that it can no longer be done within the constructor and the default behavior no longer suffices.
I'd like to introduce a factory and register it using a custom FactoryAttribute on the producer itself. This is what I have in mind:
[Export(typeof(IProducer))]
[Factory(typeof(ProducerFactory))]
public class Producer : IProducer
{
public Producer()
{
// perform some initialization
}
public void Produce()
{
// produce something
}
}
[Export]
public class ProducerFactory
{
public Producer Create()
{
// Perform complex initialization
return new Producer();
}
}
public class FactoryAttribute : Attribute
{
public Type ObjectType
{
get;
private set;
}
public FactoryAttribute(Type objectType)
{
ObjectType = objectType;
}
}
If I had to write the "new" code myself, it may very well look as follows. It would use the factory attribute, if it exists, to create a part, or default to the MEF to create it.
public object Create(Type partType, CompositionContainer container)
{
var attribute = (FactoryAttribute)partType.GetCustomAttributes(typeof (FactoryAttribute), true).FirstOrDefault();
if (attribute == null)
{
var result = container.GetExports(partType, null, null).First();
return result.Value;
}
else
{
var factoryExport = container.GetExports(attribute.ObjectType, null, null).First();
var factory = factoryExport.Value;
var method = factory.GetType().GetMethod("Create");
var result = method.Invoke(factory, new object[0]);
container.ComposeParts(result);
return result;
}
}
There are a number of articles how to implement a ExportProvider, including:
MEF + Object Factories using Export Provider
Dynamic Instantiation
However, the examples are not ideal when
The application has no dependencies or knowledge of Producer, only IProducer. It would not be able to register the factory when the CompositionContainer is created.
Producer is reused by several applications and a developer may mistakenly forget to register the factory when the CompositionContainer is created.
There are a large number of types that require custom factories and it may pose a maintenance nightmare to remember to register factories when the CompositionContainer is created.
I started to create a ExportProvider (assuming this would provide the means to implement construction using factory).
public class FactoryExportProvider : ExportProvider
{
protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition,
AtomicComposition atomicComposition)
{
// What to do here?
}
}
However, I'm having trouble understanding how to tell MEF to use the factory objects defined in the FactoryAttribute, and use the default creation mechanism if no such attribute exists.
What is the correct manner to implement this? I'm using MEF 2 Preview 5 and .NET 4.
You can make use of a property export:
public class ProducerExporter
{
[Export]
public IProducer MyProducer
{
get
{
var producer = new Producer();
// complex initialization here
return producer;
}
}
}
Note that the term factory isn't really appropriate for your example, I would reserve that term for the case where the importer wants to create instances at will, possibly by providing one or more parameters. That could be done with a method export:
public class ProducerFactory
{
[Export(typeof(Func<Type1,Type2,IProducer>)]
public IProducer CreateProducer(Type1 arg1, Type2 arg2)
{
return new Producer(arg1, arg2);
}
}
On the import side, you would then import a Func<Type1,Type2,IProducer> that you can invoke at will to create new instances.
Hello from C# and OOP newbie.
How can I avoid change of class on assigning derived class object to base class object in c#?
After i run code bellow i get this response
obj1 is TestingField.Two
obj2 is TestingField.Two
I expected that i will lose access to derived methods and properties (which I did) after assigning reference but I did not expect change of class in midcode :S
using System;
namespace TestingField
{
class Program
{
static void Main(string[] args)
{
One obj1 = new One();
Two obj2 = new Two();
obj1 = obj2;
Console.WriteLine("obj1 is {0}", obj1.GetType());
Console.WriteLine("obj2 is {0}", obj2.GetType());
Console.ReadLine();
}
}
class One
{
}
class Two : One
{
public void DoSomething()
{
Console.WriteLine("Did Something.");
}
}
}
While you are right, you will lose access to members declared in the derived type, the object won't suddenly change it's type or implementation. You can access only members declared on the base type, but the implementation of the derived type is used in the case of overriden members, which is the case with GetType, which is a compiler generated method which automatically overrides the base class's implementation.
Extending your example:
class One
{
public virtual void SayHello()
{
Console.WriteLine("Hello from Base");
}
}
class Two : One
{
public void DoSomething()
{
Console.WriteLine("Did Something.");
}
public override void SayHello()
{
Console.WriteLine("Hello from Derived");
}
}
Given:
One obj = new Two();
obj.SayHello(); // will return "Hello from Derived"
GetType is a virtual method gives you the dynamic type of the object.
I think you want the static type of the variable. You can't get this by calling a method on the object referenced by the variable. Instead just write typeof(TypeName), which is typeof(One) or typeof(Two) in your case.
Alternatively in your subclass you can use a new method which hides the original one instead of overriding it:
class One
{
public string MyGetType() { return "One"; }
}
class Two : One
{
public new string MyGetType() { return "Two"; }
}
class Program
{
private void Run()
{
One obj1 = new One();
Two obj2 = new Two();
obj1 = obj2;
Console.WriteLine("obj1.GetType(): " + obj1.GetType());
Console.WriteLine("obj2.GetType(): " + obj2.GetType());
Console.WriteLine("obj1.MyGetType(): " + obj1.MyGetType());
Console.WriteLine("obj2.MyGetType(): " + obj2.MyGetType());
}
}
Result:
obj1.GetType(): Two
obj2.GetType(): Two
obj1.MyGetType(): One
obj2.MyGetType(): Two
You haven't "changed class". The type of the variable obj1 is still One. You have assigned an instance of Two to this variable, which is allowed since Two inherits from One. The GetType method gives you the actual type of the object currently referenced by this variable, not the type of the declared variable itself.