Reputation: 357
Is there anything similar to the explicit keyword for constructors in C#? It only seems to affect the cast operators in C#.
Take this example:
public Foo( long value )
{
m_value = value;
}
What I'm looking for is a way to make the following code fail to compile:
int bar = 10;
Foo fail = new Foo( bar );
Is this possible in C#?
Upvotes: 1
Views: 1041
Reputation: 51
I know this is super old but this was a high-ranked search result that I came across while looking for the same answer so I thought I'd add my solution - add in (or ref, which may not have been available in 2014) to the parameters:
public class Program
{
public class DataSource
{
public int mInt;
public long mLong;
}
public class LongOnlyIn
{
public LongOnlyIn(in long pLong) { }
}
public class LongOnlyRef
{
public LongOnlyRef(ref long pLong) { }
}
public static void Main()
{
DataSource ds = new DataSource();
LongOnlyIn a = new LongOnlyIn(in ds.mInt); // Error: can't convert from "in int" to "in long"
LongOnlyRef b = new LongOnlyRef(ref ds.mInt); // Error: can't covnert from "ref int" to "ref long"
LongOnlyIn c = new LongOnlyIn(in ds.mLong); // Success!
LongOnlyRef d = new LongOnlyRef(ref ds.mLong); // Success!
}
}
Upvotes: 0
Reputation: 6683
As far as I know, I'm afraid that there isn't any equivalent in C# to the use of explicit
on constructor parameters in C++, nothing that will cause a compiler error in the way that you want. As you note, the explicit
keyword is only for use with cast operators.
int
can be implicitly casted to long
with no loss of precision, so it will be. I can't see any advantage to restricting the type in this instance.
Upvotes: 3
Reputation: 25743
One (really obscure) way of accomplishing this is to have an overload taking an int
and have the Obsolete
attribute applied to it, and pass true
for the IsError
property.
public Foo(long value)
{
m_value = value;
}
[Obsolete("Do not call this with ints", true)]
public Foo(int value)
{
throw new NotImplementedException();
}
Usage
var x = new Foo(5); // gets error
var x = new Foo(5L); // no warning / error
However, as explained in the comments, this is probably a bad solution to a problem that could be solved a much better way.
I only answered this question to be pedantic about answering the question as requested.
Upvotes: 1
Reputation: 700152
You can cause a compiler error by adding an overload of the constructor that takes an int
, and mark it as obsolete:
public class Foo {
private long m_value;
public Foo(long value) {
m_value = value;
}
[Obsolete("The constructor has to be called with a long value, not an int value.", true)]
public Foo(int value) {}
}
By specifying true
as the second parameter for Obsolete
it will cause a compiler error instead of the usual warning.
Upvotes: 15
Reputation: 23793
C# offers no equivalent to the C++ explicit
keyword.
However you can create your own Long
class where you enable only the conversions that you want (so here, do not define an implicit conversion operator to int
).
public class MyLong
{
public long Value { get; set; }
// Declare here any wanted conversion operator
}
and then:
public Foo( MyLong mylong )
{
m_value = mylong.Value;
}
This will fail to compile if called with an integer.
Upvotes: 4
Reputation: 1041
Have the constructor signature be for object instead of long, and then use typeof to see if the object was explicitly long.
Upvotes: -7