How to prevent an instantiation of an object in c# - c#

What I need is to check the parameters passed to the constructor and prevent the instantiation of the specific object in case they are treated as invalid.
What I have found is that an exception can be thrown so the object reference will end up with "null" as expected.
For example, this class will be instantiated only if the integer passed to the constructor is non negative.
class MyClass
{
public MyClass(int a)
{
if (a < 0)
{
throw new Exception();
}
}
}
Although the above works fine, I bet that c# can provide a cleaner way to do this, avoiding the extra cost of the try/catch need, each time a new object is about to be constructed.
static void Main(string[] args)
{
MyClass e1;
MyClass e2;
try
{
e1 = new MyClass(1);
}
catch(Exception) { }
try
{
e2 = new MyClass(-1);
}
catch(Exception) { }
}

In cases like this, you should consider using the Factory Pattern. You made the constructor private, and instead use a static method to return an instance.
public class Foo {
private Foo(int a) { ... }
public static Foo GetFoo(int a) {
if (a < 0) {
throw new Exception("No Foo for you!");
// or
return null;
}
return new Foo(a);
}
}
public class Program {
public static void Main() {
Foo f;
f = new Foo(); // Not allowed, ctor is private.
f = Foo.GetFoo(42); // Do this instead.
}
}
With this, you can do some pretty interesting stuff.
Here, we have a Foo class, with different sub-classes. By using the Factory Pattern, we can construct an instance of a particular Foo sub-class, without the outside world even knowing that any subclasses exist!
public abstract class Foo {
// Private implementations of Foo
// No one outside can ever construct one directly.
private class RedFoo : Foo { }
private class GreenFoo : Foo { }
private class BlueFoo : Foo { }
public static Foo GetColoredFoo(string color) {
switch (color.ToLower()) {
case "red": return new RedFoo();
case "green": return new GreenFoo();
case "blue": return new BlueFoo();
}
throw new Exception("No Foo for that color!");
}
}
public class Program {
public static void Main() {
Foo f;
f = new Foo(); // Not allowed; Foo is abstract
f = new RedFoo(); // Not allowed, RedFoo is private, inside of Foo
f = Foo.GetColoredFoo("red"); // Returns an instance of RedFoo
}
}
This moves the knowledge of "how to best construct the object you really need" into the definition of the class itself, and of course eliminates the try/catch. You could apply any logic you need inside of the static factory method.

You can go with the factory pattern, as suggested by MarcinJruaszek, by making the constructor private and add a static method:
public class myClass
{
private myClass(int a)
{
// constructor
}
public static myClass Create(int a){
if (a < 0)
{
return null;
}
return new myClass(a);
}
}
And do myClass.Create(1).

What I suggest you do is create a static method of your class that accepts the parameters you need to verify and have that return the object. I do not know of a way to abandon object creation during a constructor without throwing an Exception.

Related

Make instance of "object" to other class and call method

I want to define an object and make instance of it to other class, but I can't call the method, here's my code:
class Test1
{
public bool True_1()
{return true;}
}
class Test2
{
public bool True_2()
{return true;}
}
class MainClass
{
static void Main()
{
object a;
bool flag = true; // or false
if (flag)
a = new Test1();
else
a = new Test2();
if (a is Test1)
a.True_1(); //error before compiling
else
a.True_2(); //error before compiling
}
}
}
I know there's a way of creat an interface I_Test, and do this:
class Test1:I_Test
class Test2:I_Test
but since class Test2 is a dll from third-party so I can't add :I_Test to it,
so I want to make my code here achievable, any suggestion? thx!
If you are using the C# 7 you can use the new syntax that allows you to test and put the result of the test into a variable in a single line :
if (a is Test1 aTest)
aTest.True_1();
else if( a is Test2 aTest2)
aTest2.True_2();
If you are using older C# you can use the as operator coupled with a null test :
var aTest = a as Test1;
if (aTest != null)
aTest.True_1();
else
{
var aTest2 = a as Test2;
if (aTest2 != null)
{
aTest2.True_2();
}
}
You can also use a test and cast solution which minimizes the amount of variables, this is not recommended as that may forces the runtime to test twice (once for is and once for the cast). See this question for a more detailed response
if(a is Test1)
((Test1)a).True_1();
You can do these two solutions to solve this problem:
1. Convert a to the class that you want and then you can call the method: Try this:
static void Main()
{
object a;
bool flag = true;
if (flag)
a = new Test1();
else
a = new Test2();
if (a is Test1)
{
((Test1)a).True_1(); //So, there will be no error anymore
}
else
{
((Test2)a).True_2();
}
}
use dynamic keyword instead of object type. Try this:
static void Main()
{
dynamic a;
bool flag = true;
if (flag)
a = new Test1();
else
a = new Test2();
if (a is Test1)
a.True_1(); //So, there will be no error anymore
else
a.True_2();
}
You have to cast it first
if(a is Test1 aConverted)
aConverted.True_1();
Or older way of doing this:
if(a is Test1)
((Test1)a).True_1();
Let's say you have a third party DLL that contains a class...
class ThirdPartyClass
{
public bool Foo { get { return true;} }
}
And you want to create your own class that has a method or property in common with the third party class:
class MyClass
{
public bool Foo { get { return true;} }
}
As you mention, what you'd normally do is add an interface to the third party class, and then implement that interface in your own class. But you can't do that, as you also pointed out. And without an interface in common, you're stuck with that clunky if/then construct.
If I correctly understand your situation, you can deal with it as follow. Extend the third party class to add the interface, like so:
interface IMyInterface
{
bool Foo { get; }
}
class MyThirdPartyClass : ThirdPartyClass, IMyInterface
{
}
Since Foo is public, it will get inherited and be available, and satisfy the interface. And now you can create your own class too:
class MyClass : IMyInterface
{
public bool Foo { get { return true; }}
}
And you can use them interchangeably:
IMyInterface a = new MyThirdPartyClass();
IMyInterface b = new MyClass();
bool c = a.Foo;
bool d = b.Foo;
That's how I would do it.
You may run into a problem if the third party class is sealed. If that is the case, you have to wrap it instead of inheriting from it:
class MyThirdPartyClassWrapper : IMyInterface
{
private readonly ThirdPartyClass _wrappedInstance = new ThirdPartyClass();
public bool Foo { get { return _wrappedInstance.Foo; } }
}
And then it'll still work:
IMyInterface a = new MyThirdPartyClassWrapper();
IMyInterface b = new MyClass();
bool c = a.Foo;
bool d = b.Foo;

Implementing FactoryPattern without using an Interface C#

I have a requirement of refactoring the code where I have multiple classes and the object of the classes need to be created dynamically depending upon the user request. Now the classes are all there and have no common methods within them that match each other. So I cannot add an interface to it and create a factory class that will return the interface reference referencing the actual class. Is there a way with generics or any other way to refactor this to be able to create objects dynamically. The approach we have now is that there is a main class where the object of each class is instantiated and all methods are being called. Can we implement a factory pattern without an interface or any solution to my scenario ? Please.
Adding sample code to explain the scenario.
public interface ITest
{
string TestMethod1(string st, int ab);
int TestMethod2(string st);
void TestMethod4(int ab);
float ITest.TestMethod3(string st);
}
public class Class1 : ITest
{
public string TestMethod1(string st, int ab)
{
return string.Empty;
}
public void TestMethod4(int ab)
{
throw new NotImplementedException();
}
public int TestMethod2(string st)
{
throw new NotImplementedException();
}
public float TestMethod3(string st)
{
throw new NotImplementedException();
}
}
public class Class2 : ITest
{
float ITest.TestMethod3(string st)
{
return float.Parse("12.4");
}
void ITest.TestMethod4(int ab)
{
throw new NotImplementedException();
}
public string TestMethod1(string st, int ab)
{
throw new NotImplementedException();
}
public int TestMethod2(string st)
{
throw new NotImplementedException();
}
}
public class Main
{
ITest test = null;
public ITest CreateFactory(TestType testType)
{
switch(testType)
{
case TestType.Class1:
test = new Class1();
break;
case TestType.Class2:
test = new Class2();
break;
}
return test;
}
}
enum TestType
{
Class1,
Class2
}
So, as in above, I can't have the interface because no common methods are in it. So what other solutions I can have, if I have an empty interface or abstract method, how will that help. Even if I put one common method in the interface and all classes implement it, since I am passing the reference to the interface, I can only access the common method from the interface reference.
My idea is to use something like the below, but not sure what the return type would or should be defined as.
public T CreateFactory(TestType testType)
{
switch(testType)
{
case TestType.Class1:
return GetInstance<Class1>("Class1");
case TestType.Class2:
return GetInstance<Class1>("Class2");
}
return null;
}
public T GetInstance<T>(string type)
{
return (T)Activator.CreateInstance(Type.GetType(type));
}
How do I define T here in the return is my concern and how can I invoke it, if anybody can help with that, then I think I am close to the solution.
Answer to my problem
public static T CreateFactory<T>()
where T: IFactory, new()
{
return new T();
}
I'm not saying totally understand the problem, but give it a shot...
Factory like class that you have:
class Factory
{
public static Visitable Create(string userInput)
{
switch (userInput)
{
case nameof(ClassA):
return new ClassA();
case nameof(ClassB):
return new ClassB();
default:
return null;
}
}
}
Types that you have to create:
class ClassA : Visitable
{
public void M1(){}
public override void Accept(Visitor visitor){visitor.Visit(this)}
}
class ClassB : Visitable
{
public void M2(){}
public override void Accept(Visitor visitor){visitor.Visit(this)}
}
Usage of the code:
var visitor = new Visitor();
var obj = Factory.Create("ClassA");
obj.Accept(visitor);
And the missing parts:
class Visitor
{
public void Visit(ClassA obj){ obj.M1(); } // Here you have to know what method will be called!
public void Visit(ClassB obj){ obj.M2(); } // Here you have to know what method will be called!
}
abstract class Visitable
{
public abstract void Accept(Visitor visitor);
}
This is called the Visitor pattern. If you know what methods need to be called Visitor.Visit than that is what you want.
I don't entirely understand your question but a basic assertion is wrong. I am concerned with your design given the basis of your question.
Regardless, my proposed solution:
You are saying that you don't have a common object (indirect, directly you stated: "I can't have the interface because no common methods are in it."
object is the common element.
I don't condone this but you could create a factory object that just returned object as the data type. The problem with this is you then have to cast it after the object creation which you may not mind...
internal class MyFactory
{
internal object CreateItem1() { return ...; }
internal object CreateItem2() { return ...; }
internal object CreateItem2(ExampleEnum e)
{
switch(e)
{
case e.Something:
return new blah();
default:
return new List<string>();
}
}
}

Singleton classes containing fields of each other null reference exception

In my application I need to have few singleton classes. Each of them has some fields of others singleton classes to use them. Below I reconstructed the issue on simple example:
public sealed class A
{
private B b = B.Instance;
private static readonly A instance = new A();
public static A Instance { get { return instance; } }
static A() { }
private A() { }
public void Do()
{
b.ToString();
}
}
public sealed class B
{
A a = A.Instance;
private static readonly B instance = new B();
public static B Instance { get { return instance; } }
static B() { }
private B() { }
public void Do()
{
a.ToString();
}
}
class Program
{
static B b = B.Instance;
static A a = A.Instance;
static void Main(string[] args)
{
b.Do();
a.Do();
}
}
Null reference exception coming because fields are null. So how can I initialize and use such interconnected singleton classes?
The constructors don't run in parallel so when the first is being created the second Singleton has not yet been created.
Instead of setting the property to the value directly you'd likely write something like this in class B:
private A AProp {
get {
if(a == null)
a = A.Instance;
return a;
}
}
You'd do the same the other way round in class A. So getting the value is delayed until first access and at that time the other Singleton has already been created.
In what scenario exactlly something like this is a good idea is another question. Especially given that instead of accessing it in a local field you could always just access it using A.Instance anyway (so the local field becomes kind of redundant at that point.

How pass delegate to a method, where delegates are non static?

I'm just beginning understanding delegates, I have a class that implemens IDisposable:
public class MyClass : IDisposable
{
public delegate int DoSomething();
public int Zero() {return 0;}
public int One() {return 1;}
public void Dispose()
{
// Cleanup
}
}
A method (defined in an another class) that is using MyClass:
public class AnotherCLass
{
public static void UseMyClass(MyClass.DoSomething func)
{
using (var mc = new MyClass())
{
// Call the delegate function
mc.func(); // <-------- this is what i should actually call
}
}
}
The actual question: how pass the Zero() function to UseMyClass method? Do I have to create an instance of MyClass (I would like to avoid this...)?
public static void main(string[] args)
{
// Call AnotherClass method, by passing Zero()
// or One() but without instatiate MyCLass
AnotherClass.UseMyClass(??????????);
}
Is your intent that the instance is provided by the caller of the delegate, and not the creator of the delegate? C# does support such an unbound delegate, it's called an open delegate, and the instance becomes a parameter.
You have to use Delegate.CreateDelegate to create an open delegate, something like this:
public class MyClass : IDisposable
{
public delegate int DoSomething();
public int Zero() {return 0;}
public int One() {return 1;}
public void Dispose()
{
// Cleanup
}
}
public class AnotherCLass
{
public static void UseMyClass(Converter<MyClass,int> func)
{
using (var mc = new MyClass())
{
// Call the delegate function
func(mc);
}
}
}
AnotherClass.UseMyClass(
(Converter<MyClass, int>)Delegate.CreateDelegate(
typeof(Converter<MyClass, int>),
typeof(MyClass).GetMethod("One")
)
);
Of course, you can do it much more easily with a shim:
AnotherClass.UseMyClass( mc => mc.One() ); // C# 3 or later
AnotherClass.UseMyClass( delegate(MyClass mc) { return mc.One(); } ); // C# 2
Because it's an instance method, if you want to call it, you need an instance. That's simply how the CLR works. However, there are two options you could go with:
Make the member functions static. If they're as simple as returning a static value, there's no reason for them to be instance methods. However, if you do actually require instance data...
Use a singleton instance. This way you don't need to create a new instance every time you want to call your static method.
You can do the latter like this:
public class MyClass
{
private static MyClass singletonInstance;
public static MyClass SingletonInstance
{
get
{
if (singletonInstance == null)
{
singletonInstance = new MyClass();
}
return singletonInstance;
}
}
// the rest of your class implementation
}
Then, you can call your static method like so:
AnotherClass.UseMyClass(MyClass.SingletonInstance.Zero);
Cant be done without instantiation. Heres how you can do it:
public static void main(string[] args)
{
// Call AnotherClass method, by passing Zero()
// or One() but without instatiate MyCLass
AnotherClass.UseMyClass((new MyClass()).Zero);
}

Subclass constructor exception leaves parent class instance

Sorry for a lot of code to read. It's the simplest way to show the problem.
using System;
using System.Collections.Generic;
namespace P1
{
class A
{
static Dictionary<int, A> a = new Dictionary<int, A>();
static int i = 0;
int id;
public A()
{
id = ++i;
a[id] = this;
}
public static int Count() { return a.Count; }
}
class B : A
{
public B()
{
throw new Exception();
}
}
class Program
{
static void Main(string[] args)
{
try
{
var b = new B();
}
catch
{
// What should be here ????
}
Console.WriteLine(A.Count()); //prints 1 - not good
Console.ReadKey();
}
}
}
Can anyone suggest cleanup logic for case when subclass constructor fails?
You will need to put the cleanup logic in the constructor of B, since you cannot have access to the instance reference after the constructor fails.
Here is an example on how you could do this:
class A
{
static Dictionary<int, A> a = new Dictionary<int, A>();
static int i = 0;
int id;
public A()
{
id = ++i;
a[id] = this;
}
protected void Destroy()
{
a.Remove(id);
i--;
}
public static int Count() { return a.Count; }
}
class B : A
{
public B()
{
try
{
throw new Exception();
}
catch (Exception)
{
Destroy();
throw;
}
}
}
Your base class constructor is being called before the exception is thrown, so the object has already been created and assigned to it's spot in a. If you want the object to not be created by the constructor, then you might want to consider a static method to instantiate a new A instead of using the default constructor. Then, when the instantiation of the object fails (in B) you'll throw the exception before the object is added to the dictionary.

Categories