Can a public and private non-overloaded constructors exist? - c#

Any way to have a private constructor coexist with the public one with the same signature? I've included bare bones code.
struct Wouble
{
private double value;
public Wouble(double value)
{
this.value = ExpensiveValidation(value);
}
private Wouble(double value)
{
this.value = value;
}
public static implicit operator Wouble(double value)
{
return new Wouble(value);
}
public static Wouble operator +(Wouble a, Wouble b)
{
// Would like this to call the private constructor without ExpensiveValidation
new Wouble(a.value + b.value);
}
}
...
Wouble a = new Wouble(5.2);
Wouble b = new Wouble(8.1);
Wouble c = a + b; // Calls overloaded operator +, I don't want to validate again
The only workaround I could think of is to add a dummy unused parameter to the private constructor to force an overload like this:
private Wouble(double value, int dontValidate)
{ this.value = value; }
and pass a extra ,0 into all internal calls. I also want it to be performant, no unnecessary helper methods etc.

You can try using constructor without parameters (note, that struct always has it):
struct Wouble
{
private double value;
public Wouble(double value)
{
this.value = ExpensiveValidation(value);
}
public static implicit operator Wouble(double value)
{
// ExpensiveValidation will be performed
return new Wouble(value);
}
public static Wouble operator +(Wouble a, Wouble b)
{
// No validation here
return new Wouble()
{
value = a.value + b.value
};
}
}
Then
// Expensive validation will be performed
Wouble a = new Wouble(5.2);
// Expensive validation will be performed
Wouble b = new Wouble(8.1);
// No expenisive validation, 5.2 + 8.1 = 13.3 is assigned to value
Wouble c = a + b;

While #Dmitry gave you an answer (a good one), it is worth noting that you are, perhaps, mixing concerns (performance) with overloading (about functionality/behavior), and this can lead to all kinds of issues.
The two concepts are orthogonal (unrelated) so trying to conflate them is counterproductive. I would suggest conveying intent through some other mechanism. Maybe introduce a factory class that does the validation, and leave "normal" initialization to the constructor.
Constructors, generally, should avoid excessive computation.
Going back to the original question, we know now that the short answer is "no, you cannot have the same constructor only vary by access modifier". Overloading is based on the signature of the method by parameter count and type. Return type (if it was a method and not a constructor, and access modifiers are not part of overload resolution).

Related

Any way to use interfaces as "type aliases" in C#?

Basically I want to use my own types instead of primitives like int/double, but still pass around these primitive values. Something like:
interface IInt {} // My interface to represent int. If I could fake so "int" implements this, all would work.
interface IPostNumber : IInt {} // Post number is an int. But int is not type safe enough for me.
void MyFunction(IPostNumber postNumber); // My function that should accept int/IPostNumber.
MyFunction(42); // This could also work with implicit conversion, but not allowed for interfaces:(
From ispiro's suggestion I found something that should cover everything.
So I declare my interfaces independent of underlying representation, e.g.
public interface IPostNumber{}
public interface IPostNumberFrom : IPostNumber{}
public interface IPostNumberTo : IPostNumber{}
These have full interface generality such as multiple inheritance. Then the data representation is done with generic classes with implicit conversion:
public class CInt<T>
{
public int value;
public static implicit operator int(CInt<T> d) => d.value;
public static implicit operator CInt<T>(int b) => new CInt<T>() { value = b };
}
Functions that accepts IPostNumber with int, is done as such:
private int TestPostNumberInt(CInt<IPostNumber> i) => i;
private int TestPostNumberFrom(CInt<IPostNumberFrom> i) => i;
CInt<IPostNumber> a = 4; // Works
Assert.Equal(1, TestPostNumberInt(1)); // Works
Assert.Equal(1, TestPostNumberFrom(a)); // Don't compile with IPostNumber into IPostNumberFrom
Now I can always declare CString<IPostNumber>, if some post numbers are represented with string. Or a function could accept the IPostNumber interface itself, if I make some class of it. Now one little issue is that if I want to pass CInt<IPostNumberFrom> to TestPostNumber, the method must be generic with T : IPostNumber, like this:
private int TestPostNumberInt<T>(CInt<T> i) where T : IPostNumber => i;
private int TestPostNumberIntFrom<T>(CInt<T> i) where T : IPostNumberFrom => i;
and then the generic type will not be detected while using implicit conversion (must cast). But we'll see if this is a big deal.
Also for later consideration: I will have class CJSON<T> : CString<T>. From what I see it works, though argubly CJSON could have different representations as well, like byte[] in some context. (But this is taking things far). So just need to think hard about representation vs. interfaces for my domain concepts.
I think what you might be looking for are implicit operators, but unfortunately I believe they're not supported for interfaces in the C# language specification. You can do this with subclasses if need be. Here's an example:
public class MyInt
{
int SomeValue;
public TestInt(int i)
{
SomeValue = i;
}
public static implicit operator MyInt(int i)
{
return new MyInt(i);
}
public static implicit operator int(MyInt myInt)
{
return myInt.SomeValue;
}
}
To assign using an implicit operator, you can do this:
MyInt n = 3;
int x = n;
See: implicit operator using interfaces
Is it this you're looking for?
public class IInt
{
public int TheInt;
public IInt(int theInt)
{
TheInt = theInt;
}
}
and then either use:
IInt i = new IInt(42);
MyFunction(i);
or define MyFunction for int and then use:
IInt i = new IInt(42);
MyFunction(i.TheInt);
Just one more idea:
public class IInt<T> where T : struct
{
public T TheInt;
public IInt(T theInt)
{
TheInt = theInt;
}
}
You can create an extension method but that method should be explicitly called.

Why is an implicit operator static?

I notice that an implicit operator is required to be called static but it actually is not really static at all... How come the implicit operator cannot be accessed statically but it can be accessed through an instance. This is the complete opposite of static. Suppose I wanted a static static implicit operator so that I could implicitly convert the static states of a class.
For example
a = new b(); // implicitly converts b to a.
a = b(); // implicitly convert the static states of b to a.
So for example b is a non-static class because it has a form but for all intents and purposes it is static and all instances are sharing the same information so I want to implicitly convert the class' static internals.
I will try to go into more detail of my example since Jeff thinks it makes no sense.
class b displays a dialog form, but it saves all the information entered into static variables. This is because the instances of b are only to display the dialog form and the data entered is one logical block of data(there is only one logical instance of the data entered). All the static variables fit directly into class a and so I can seamlessly convert the static variables in b to an instance of a class, however I would like to use implicit operator for this task instead of having a separate method. But it laments me that I cannot have an actual static implicit operator. Perhaps I am misunderstanding the word static and I am only using it in terms of how it works with methods and classes.
If an operator was not static, it could not handle null operands.
This applies equally to the case of an implicit conversion operator:
public class MyClass
{
public MyClass(int x)
{
this.X = x;
}
public int X { get; private set; }
public static implicit operator int(MyClass operand)
{
if (operand == null)
{
return 0;
}
return operand.X;
}
}
internal class Program
{
internal static void Main(string[] args)
{
MyClass x = null;
int y = x; // What instance would a non-static operator use here?
}
}
In C#, all operator definitions are static, see for instance http://msdn.microsoft.com/en-us/library/aa288467(v=vs.71).aspx
-Binary operator definitions, of course, because it would be arbitrary to declare one or the other to be this.
-Unary operator definitions, to match the theme of binary operator definitions being static.
It is just convention that it is done this way.
No operator works on the 'static state' of a class (except possibly typeof). In other words it's not possible to do anything like this:
var result = System.Int32 + System.Int32;
Operators only work on instances of a class.
int a = ..., b = ...;
var result = a + b;
All operators are necessarily static, so there's no need to disambiguate between 'normal static' operators and 'static static' operators.
You might consider using a singleton pattern. Something like this:
public class Foo
{
public int Member { get; set; }
private static Foo instance = new Foo();
public static Foo Instance { get { return instance; } }
private Foo()
{
}
public static implicit operator int(Foo foo)
{
return foo.Member;
}
}
Then you can use it as:
int a = Foo.Instance;
Here's a second answer from me, trying to guess at your underlying problem (instead of answering the question in the title, as I did in my first answer):
From the editted question and comments, it looks like you are trying to:
ensure that there is only a single instance of an InputBox class.
Convert data in the input box class to a string.
I'd make sure that you really need to enforce only a single instance of the InputBox class, but if that requirement is well founded then you could do something like this, using the Singleton pattern, and overriding the ToString instance method.:
class InputBox
{
static InputBox Instance = new InputBox();
int someNumber;
string someText;
private InputBox()
{
}
// ...
public override string ToString()
{
return someNumber.ToString() + " " + someText;
}
}
Usage:
string result = InputBox.Instance.ToString();
Addendum:
If it's really all about the syntax you want to use, you could add a delegate like this:
// Please don't really do this ;)
Func<string> InputBox = () => MyNamespace.InputBox.Instance.ToString();
And then use it like this:
string result = InputBox();
But anyone reading your code would cry ;)

Initialize object by assignment?

How to give types the ability to initialize via an assignment, some like the following:
public struct WrappedByte
{
private byte m_value;
}
//Usage:
WrappedByte x = 0xFF;
You need to use a custom implicit operator. Note that this doesn't just apply to structs.
public struct WrappedByte
{
private byte m_value;
public static implicit operator WrappedByte(byte b)
{
return new WrappedByte() { m_value = b };
}
}
Also note that this won't apply just to initialization; it will mean that you can supply a byte in any location that a WrappedByte is expected. It also includes assignments other than initializations, parameters to methods, etc.

How do you make this parameter access syntax possible?

public class SampleClass {
public int value;
public SampleClass(int v)
{ value = v; }
}
// i want to access value like this
SampleClass sc = new SampleClass(5);
int i = sc;
Is there a way to do this in C#? I don't want to have to say sc.Value every time i need to access the value.
Use an implicit conversion:
public class SampleClass {
public int value;
public SampleClass(int v)
{ value = v; }
public static implicit operator int (SampleClass c)
{
return c.value;
}
}
You should look into properties however.
You can do it by including an implicit conversion from SampleClass to int:
public static implicit operator int(SampleClass s)
{
return s.value;
}
... but I would strongly recommend that you don't do so, or at least that you think very carefully beforehand. Implicit conversions make it harder to reason about the language in various ways (consider things like overload resolution, for example).
Very, very occasionally it's a good idea to introduce implicit conversions - for example LINQ to XML makes great use of it with string to XNamespace and string to XName conversions - but I wouldn't do it here just to avoid having to use .Value.
It's slightly more reasonable to make an explicit conversion (just change implicit to explicit in the operator conversion) in that at least that makes it clear-ish what's going on in the calling code... but at that point there's really not much difference in source size between a cast to int and using .Value.
(And as suggested elsewhere, don't make fields public - use properties instead.)
Take a look at this. You need to overload the implicit cast operator for int.
Yes, it's possible. You need to implement implicit for your SampleClass:
Here it is:
public class SampleClass
{
public int Value;
public SampleClass(int v)
{
Value = v;
}
public static implicit operator int(SampleClass d)
{
return d.Value;
}
}

How to create a generic C# method that can return either double or decimal?

I have a method like this:
private static double ComputePercentage(ushort level, ushort capacity)
{
double percentage;
if(capacity == 1)
percentage = 1;
// do calculations...
return percentage;
}
Is it possible to make it of a generic type like "type T" where it can return either decimal or double, depending on the type of method expected (or the type put into the function?)
I tried something like this and I couldn't get it to work, because I cannot assign a number like "1" to a generic type. I also tried using the "where T :" after ushort capacity) but I still couldn't figure it out.
private static T ComputePercentage<T>(ushort level, ushort capacity)
{
T percentage;
if(capacity == 1)
percentage = 1; // error here
// do calculations...
return percentage;
}
Is this even possible? I wasn't sure, but I thought this post might suggest that what I'm trying to do is just plain impossible.
EDIT
Thanks to all who responded, many good answers. As Tomas pointed out, this is probably best done in two separate methods. As pointed out by both TreDubZedd and TcKs, the best way to get the functionality I would want is to use an implicit conversion that could return either a double or decimal implicitly.
In fact, you don't need generics but overloading. However you need overloading by return value's type which is supported by IL but is not supported by C#.
I prefere two methods for every return's value type:
static double ComputePercentageDouble (ushort level, ushort capacity)
static decimal ComputePercentageDecimal (ushort level, ushort capacity)
The alternative can be custome type with implicit cast operators:
decimal decimalPercentage = ComputePercentage( 1, 2 );
double doublePercentage = ComputePercentage( 1, 2 );
static DoubleDecimal ComputePercentage( ushort level, ushort capacity ) {
DoubleDecimal percentage = default( DoubleDecimal );
if ( capacity == 1 )
percentage.Number = 1; // error here
// do calculations...
return percentage;
}
public struct DoubleDecimal {
public decimal Number;
public static implicit operator decimal( DoubleDecimal value ) {
return value.Number;
}
public static implicit operator double( DoubleDecimal value ) {
return (double)value.Number;
}
}
You might be able to use implicit conversion: http://msdn.microsoft.com/en-us/library/zk2z37d3.aspx
Generics are useful for writing code that works with any types (perhaps implementing some interface, which can be specified using where). However, if you want to use them for implementing method that can return two different numeric types, it feels a bit wrong (it would work only if double and decimal implemented some shared interface).
You should probably define two distinct methods (e.g. ComputePercentage and ComputePercentagePrecise or something like that - since you can't use overloading using different parameters).
It may be possible to workaround this limitation by using something like this (but that's probably overly complicated for you):
class INumericOps<T> {
public abstract T One { get; }
public abstract T Add(T a, T b);
// and other operations that you may need
}
// Implementations of numeric operations for decimal and double
class DecimalNumerics : INumericOps<decimal> { ... }
class DoubleNumerics : INumericOps<double> { ... }
Then you would write a method that takes INumericOps<T> as a type parameter and uses it to do all mathematics inside the method:
private static R ComputePercentage<T, R>(ushort level, ushort capacity)
where T : INumericOps<R>, where T : new() {
INumericOps<R> ops = new T(); // Get instance with numeric operations
T percentage;
if(capacity == 1)
percentage = ops.One;
// Calculations using ops.Add(.., ..) instead of + etc.
return percentage;
}
Then you would call it like this:
decimal res = ComputePercentage<DecimalNumerics, decimal>(...);
This is a nice trick and it is probably the best (type-safe) workaround you can get. However, it is a bit complicated, so declaring two separate methods may be a better idea.
It's not pretty, but try:
percentage = (T)Convert.ChangeType(1, typeof(T));
This works for both double and decimal at least.
If you're using C# 4.0 you could just return a dynamic.
private static T ComputePercentage<T>(ushort level, ushort capacity)
{
if (typeof(T) == typeof(decimal))
{
decimal percentage = 1;
return (T) (object) percentage;
}
if (typeof(T) == typeof(double))
{
double percentage = 1;
return (T) (object) percentage;
}
throw new NotSupportedExcpetion();
}
Why not create a Percent class?
class Percent
{
public Percent(double value)
{
this.value = value;
}
public double AsDouble()
{
return value;
}
public decimal AsDecimal()
{
return (decimal)value;
}
readonly double value;
}
static Percent ComputePercentage(ushort level, ushort capacity)
{
double percentage = 0;
if (capacity == 1)
{
percentage = 1;
}
// calculations
return new Percent(percentage);
}

Categories

Resources