How do I do implicit conversion without creating a new instance? - c#

I've got a class which looks like this
class MyClass
{
string myData;
//.....
//other fields
public static implicit operator string(MyClass c)
{
return c.myData;
}
}
Now when I assign the value of the class to a string, I get myData's value. But in microsoft's example, to do implicit convection from MyClass to string, I'd have to create a new instance of MyClass in a static method. I don't want to do this, instead I want to simply assign the string's value to myData field.
Is this possible to do in c#, and if it is, how do I do it?

Sounds like there is no direct solution to what you need. I would suggest to try operator overloading and this would allow to perform some of the things I think you need with the understanding that = (equal) cannot be overloaded probably you would like to try += You can find additional help here:
http://msdn.microsoft.com/en-us/library/6fbs5e2h.aspx
This is a sample version:
namespace ConsoleApplication1
{
public struct MyClass
{
public string MyData {get;set;}
// Constructor.
public MyClass(string obj1):this()
{
this.MyData = obj1;
}
public static MyClass operator +(MyClass c1, string var3)
{
return new MyClass(var3);
}
public override string ToString()
{
return (System.String.Format("{0} ", this.MyData));
}
}
[System.Runtime.InteropServices.GuidAttribute("D36900FE-8902-4ED8-B961-DE5B3F3273AC")]
class Program
{
static void Main(string[] args)
{
MyClass obj1 = new MyClass();
obj1 += "Hello";
Console.ReadKey();
}
}
}

Related

c# how assign static class to instance variable?

Static members can't be called with instance, like instance.myStaticProperty.
Is there any way, that I can have an instance variable that will be an alias of static self class? like:
class myClass
{
public string a ="hello";
public static string b ="world";
public myClass myVariable = global::myClass; // <--- phseudo code
}
and i could call:
myClass instance= new myClass();
instance.myVariable.b; //
No, there is not. The closest you get is using a using.
Your static class definition:
class ClassA
{
public static string A = "A";
}
And to use it:
using StaticClassA = ConsoleApp1.ClassA;
class Program
{
static void Main(string[] args)
{
string a = StaticClassA.A;
}
}
Not too much to gain though, but it might ease your naming a little.
Another (somewhat cooler) option is a static using:
using static ConsoleApp1.StaticClassA;
class Program
{
static void Main(string[] args)
{
string a = A;
}
}
You're attempting to do an anti-pattern there.
Static properties are properties not defined in an instance (object) of that class, but by the class itself. And as such, you can access and modify them whenever you choose to, provided you have the required scopes to do so.
I don't see the problem in calling MyClass.StaticProperty = <some expression>, if indeed the functions the static property do, are static. If it's something part of the object, something you don't connect with the class itself, i.e it might be different for each instanced object of that class, then just turn it into a regular property instead.
Example of some static properties and methods:
public class DoMath
{
public static string Pi { get; private set; } = "3.14";
public static double X {get; set;}
public static double Y {get; set;}
public static double Sum() => X + Y;
}
DoMath.X = 3.5;
DoMath.Y = 4;
double result = DoMath.Sum();
Console.WriteLine($"Pi is equal to {DoMath.Pi}.");
If you truly wish something to be static, then don't try to make it non-static. Simply declare it as such.
Static members are shared across all instances of the class or all instances of Class Of T of same T.
So you can access static properties outside of class by using the ClassName.VarName or directly by the VarName from within the class.
You can access static fields and properties and methods from all non static methods.
You can also add an instance member mapping a static member.
Instances of a static thing can't exist in addition to the static existence itself.
So you can write this:
class myClass
{
public string a = "hello";
static public string b = "world";
public string B { get { return b; } set { b = value; } }
public void DoSomething()
{
b = "new world";
}
}
And use it like that:
myClass instance= new myClass();
instance.DoSomething();
myClass.b = "another world";
instance.B = "C# world";

Switching out the 'this' pointer for a static class member in the constructor

Suppose I had a class with static members of itself, just like a singleton.
I also allow the construction of that class.
If a consumer constructs with known arguments I want to return a static member instead of a new construction.
Below is non compiling example code that illustrates the point.
Essentially I want the class to be constructed like illustrated in the Construct method but I do not want the consumer of the class to be forced into rewriting his existing new MyClass(0) calls.
Is that possible?
public class MyClass
{
public static readonly MyClass Zero = new MyClass(0);
private int n;
public static MyClass Construct(int n)
{
MyClass self = new MyClass(0, true); //the bool just helps with referencing
ReplaceIfZero(ref self);
return self;
}
public MyClass(int n, bool x) //the bool is just so i can reference it in this example
{
this.n = n;
}
public MyClass(int n)
{
this.n = n;
ReplaceIfZero(ref this);
// Error CS1605 Cannot pass 'this' as a ref or out argument because it is read - only
}
ReplaceIfZero(ref MyClass myclass)
{
if(Zero.Equals(myclass))
{
myclass = Zero;
}
}
public override bool Equals(object obj)
{
return ReferenceEquals(this, obj) || ( (obj is MyClass) && n.Equals((obj as MyClass).n) );
}
}
The normal solution to this is to make the constructor private and add a public static factory method that takes care of things. I think that would be the best approach.
However, another approach is the use an interface and a wrapper class to hide away the details.
Something like this:
public interface IMyClass
{
int SomeMethod(int x);
}
public class MyClass: IMyClass
{
public MyClass(int n)
{
_impl = MyClassImpl.Create(n);
}
public int SomeMethod(int x)
{
return _impl.SomeMethod(x);
}
// For test purposes only - see later in this answer.
public bool ImplementationEquals(MyClass other)
{
return ReferenceEquals(_impl, other._impl);
}
readonly IMyClass _impl;
}
internal class MyClassImpl : IMyClass
{
static readonly ConcurrentDictionary<int, IMyClass> _dict = new ConcurrentDictionary<int, IMyClass>();
readonly int _n;
MyClassImpl(int n)
{
_n = n;
}
public static IMyClass Create(int n)
{
return _dict.GetOrAdd(n, i => new MyClassImpl(i));
}
public int SomeMethod(int x)
{
return _n + x;
}
}
Then client code can create instances of MyClass, and behind the scenes another class is used for the implementation.
If the client code creates two instances of MyClass, the implementing object will be shared, as this code demonstrates:
var a = new MyClass(1);
var b = new MyClass(2);
var c = new MyClass(1);
Console.WriteLine(a.ImplementationEquals(b)); // Prints false
Console.WriteLine(a.ImplementationEquals(c)); // Prints true
Also note that if you do something like this, it's very important that the class is strongly immutable (i.e. all of its fields are immutable, and if a field is not a primitive type, all of its fields are recursively immutable)
As I mentioned in the comments, C# does not allow you to change the result of the new operator. It always returns a new instance of class. Of course we are speaking about normal classes and not special hacks like ContextBoundObject and proxies.
So there is no way to keep your clients using the new operator and get the desired behavior. You need to remove the public constructors and force your clients to use some public static factory method like MyClass.Create (or Construct as in your example).
As far as I understand from your code, You want to provide the same object if user creates the same number for another instance. If then it is better to user factory pattern or singleton pattern
Well, you seem to want only one instance of your class.
Would be easier to create a static class, no ?
public static class MyClass
{
static MyClass()
{
n_ = 2;
}
private static int n_;
public static void Construct(int number)
{
n_= number;
}
}

How to return a property of the class instead of the class itself?

I'm currently converting and casting from Class to Class2 using the implicit operator.
But what I want to do is, that, whenever I refer to foo (Class<Class2>), I'd like for Goo(Class) to be returned so that I can access the public Properties of it directly, without having to cast it first into a new variable.
In other words, I want that when I access Class<Class>, I'd like Goo to be returned.
I'm aware I might have not been able to explain properly so feel free to ask in the comment section so that I can try to fill in even better on what I mean. Thanks in advance!
class Class<T> where T : new()
{
public T Goo;
public Class() { Goo = new T(); }
public static implicit operator T(Class<T> Loo)
{
return Loo.Goo;
}
}
class ClassX
{
public byte[] SharedData;
public ClassX() { }
}
class Class2 : ClassX
{
public byte Data;
public Class2() { }
}
class Class3 : ClassX
{
public string Data;
public Class3() { }
}
class Program
{
static void Main(string[] args)
{
Class<Class2> foo = new Class<Class2>();
Class2 poo = foo;
foo.Data = 0xFF; // Error - I want this to work, tho.
poo.Data = 0xFF; // Works - Not what I want to use.
System.Console.ReadLine();
}
}
EDIT #1: Updated the code.
you should be able to do it quite simply as you have already instantiated it within the class.
Class2 main = foo.Goo

Create an instance of a class from an instance of the type of its generic parameter

I want to do this:
public class ValueContainer<T> {
public T Value { get; set; }
}
Then I want to assign a value to it like this:
private ValueContainer<string> value;
value = "hello";
I'm sure I've seen this somewhere but can't figure out how to do it.
TIA
You can use a custom implicit operator, e.g:
public static implicit operator ValueContainer<T>(T value) {
return new ValueContainer { Value = value };
}
While this is a nice language feature of C#, it is not CLS compliant and won't be supported by other .NET languages like VB.NET, so if you are designing types to be reused with other languages, its worth baring that in mind.
Creating your own implicit operator will take care of this problem.
class Program
{
static void Main(string[] args)
{
Container<string> container;
container = "hello";
}
}
public class Container<T>
{
public T Value { get; set; }
public static implicit operator Container<T>(T val)
{
return new Container<T> { Value = val };
}
}

Passing static parameters to a class

As far as I know you can can't pass parameters to a static constructor in C#.
However I do have 2 parameters I need to pass and assign them to static fields before I create an instance of a class. How do I go about it?
This may be a call for ... a Factory Method!
class Foo
{
private int bar;
private static Foo _foo;
private Foo() {}
static Foo Create(int initialBar)
{
_foo = new Foo();
_foo.bar = initialBar;
return _foo;
}
private int quux;
public void Fn1() {}
}
You may want to put a check that 'bar' is already initialized (or not) as appropriate.
You can't pass parameters to a static constructor, but you can pass parameters to the class itself - via generic type parameters.
Slightly crazy this idea, however, I'll just throw it out there anyway.
Make the class generic (with a TypeParam that will provide a parameter type) and place generic constraints on it (details in code example), then derive a new parameter type, which contains virtuals that you can use to read what they want the parameter values to be.
//base parameter type - provides the 'anchor' for our generic constraint later,
//as well as a nice, strong-typed access to our param values.
public class StaticParameterBase
{
public abstract string ParameterString{ get; }
public abstract MyComplexType ParameterComplex { get; }
}
//note the use of the new() generic constraint so we know we can confidently create
//an instance of the type.
public class MyType<TParameter> where TParameter:StaticParameterBase, new()
{
//local copies of parameter values. Could also simply cache an instance of
//TParameter and wrap around that.
private static string ParameterString { get; set; }
private static MyComplexType ParameterComplex { get; set; }
static MyType()
{
var myParams = new TParameter();
ParameterString = myParams.ParameterString;
ParameterComplex = myParams.ParameterComplex;
}
}
//e.g, a parameter type could be like this:
public class MyCustomParameterType : StaticParameterBase
{
public override string ParameterString { get { return "Hello crazy world!"; } }
public override MyComplexType { get {
//or wherever this object would actually be obtained from.
return new MyComplexType() { /*initializers etc */ };
}
}
}
//you can also now derive from MyType<>, specialising for your desired parameter type
//so you can hide the generic bit in the future (there will be limits to this one's
//usefulness - especially if new constructors are added to MyType<>, as they will
//have to be mirrored on this type as well).
public class MyType2 : MyType<MyCustomParameterType> { }
//then you'd use the type like this:
public static void main()
{
var instance = new MyType<MyCustomParameterType>();
//or this:
var instance2 = new MyType2();
}
I did consider a solution that employs custom type attributes applies to a type parameter, however this is easily a better way. However, you'll now be using your class always with a generic parameter type (unless you can use the deriving+specialisation trick) - possibly too clumsy for your liking.
I'd also prefer this over the other solutions presented here as it doesn't require creating any workarounds for the static initialisation - you can still use .Net's guarantee of single-time initialisation.
A word of warning - should you be reviewing your structure?
All that said - remember, though, since you can only parameterise the static once (or in this case, each uniquely parameterised static generic) - I would be asking myself why not just pull the code that is getting the parameters to give to the static, and place it in the static constructor in the first place? That way you don't actually have to resort to strange patterns like this!
I assume you mean static members of a class? In that case, you can do this:
public class MyClass
{
public static int MyInt = 12;
public static MyOtherClass MyOther = new MyOtherClass();
}
Those static members are guaranteed to be instantiated before any class is instantiated.
If you need complex logic, do it in a static constructor:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
static MyClass()
{
MyInt = 12;
MyOther = new MyOtherClass();
}
}
Edit
Based on your edit, I'd say just assign the values to what they need to be before you instantiate the class, like so:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
}
// elsewhere in code, before you instantiate MyClass:
MyClass.MyInt = 12;
MyClass.MyOther = new MyOtherClass();
MyClass myClass = new MyClass();
That said, this method gives you no guarantee that MyInt and MyOther are set before MyClass is instantiated. It will work, but requires discipline before instantiating MyClass.
One alternative pattern you might follow looks like this:
public class MyClass
{
private static int MyInt;
private static MyOtherClass MyOther;
private static bool IsStaticInitialized = false;
public static InitializeStatic(int myInt, MyOtherClass other)
{
MyInt = myInt;
MyOther = other;
IsStaticInitialized = true;
}
public MyClass()
{
if(!IsStaticInitialized)
{
throw new InvalidOperationException("Static Not Initialized");
}
// other constructor logic here.
}
}
// elsewhere in your code:
MyClass.InitializeStatic(12, new MyOtherClass());
MyClass myClass = new MyClass();
// alternatiavely:
MyClass myClass = new MyClass(); // runtime exception.

Categories

Resources