My function returns some long value
which contains two values in lower and higher 32 bits.
I thought the best ways to handle return value
is to derive my custom type from long and provide
type extenders like GetLowerValue(), GetHigherValue().
The problem is that .NET does not allow to derive from long
If you compile that
public class SubmitOrderResult : long
{
}
you get:
cannot derive from sealed type 'long'
Why is that designed so and how can overcome it?
Thanks
As already mentioned value types in .NET are sealed so there is no way you can derive from long. You should create extension methods as suggested.
Example
public static class LongExtensions
{
public static long GetLowerValue(this long value)
{
...
}
public static long GetHigherValue(this long value)
{
...
}
}
You can't derive from any of the .NET Value Types - they are all sealed by definition.
Perhaps you could implement your GetLowerValue and GetHigherValue methods as extension methods?
My function returns some long value which contains two values in lower and higher 32 bits.
That sounds like a really, really dirty hack. It could be appropriate for close-to-metal languages (e.g. C) but not for a higher-level, object-oriented language.
In OO languages, you extend the type system, not harass existing types to do your bidding. Thus, the solution should be to create a new type which carries your information.
What you can do is write a struct with implicit conversion operators. That will work exactly the way you want:
public struct SubmitOrderResult
{
private long _result;
public SubmitOrderResult(long result)
{
_result = result;
}
public long Result
{
get { return _result; }
set { _result = value; }
}
public int GetHigherValue()
{
return (int)(_result >> 32);
}
public int GetLowerValue()
{
return (int)_result;
}
public static implicit operator SubmitOrderResult(long result)
{
return new SubmitOrderResult(result);
}
public static implicit operator long(SubmitOrderResult result)
{
return result._result;
}
}
Then you can do:
SubmitOrderResult result = someObject.TheMethod();
Console.WriteLine(result.GetHigherValue());
Console.WriteLine(result.GetLowerValue());
...just like you wanted.
If I understand correctly, your function actually returns two values, and the fact that you pack them into a long is an implementation detail. In that case, hide this detail and create a class which contains the value and the required operations:
public class SubmitOrderResult
{
private readonly long value_;
public int OneValue
{
get { return (int)(value_ >> 32); }
}
public int TheOtherValue
{
get { return (int)(value_ & 0xFFFFFFFF); }
}
public SubmitOrderResult(long value)
{ value_ = value; }
}
You can't overcome it.
As long is a sealed type and therefore you can't inherit from them. See the MSDN
Because structs are implicitly sealed, they cannot be inherited.
For more information, see Inheritance (C# Programming Guide).
Related
Reading this, I learned it was possible to allow a method to accept parameters of multiple types by making it a generic method. In the example, the following code is used with a type constraint to ensure "U" is an IEnumerable<T>.
public T DoSomething<U, T>(U arg) where U : IEnumerable<T>
{
return arg.First();
}
I found some more code which allowed adding multiple type constraints, such as:
public void test<T>(string a, T arg) where T: ParentClass, ChildClass
{
//do something
}
However, this code appears to enforce that arg must be both a type of ParentClass and ChildClass. What I want to do is say that arg could be a type of ParentClass or ChildClass in the following manner:
public void test<T>(string a, T arg) where T: string OR Exception
{
//do something
}
Your help is appreciated as always!
That is not possible. You can, however, define overloads for specific types:
public void test(string a, string arg);
public void test(string a, Exception arg);
If those are part of a generic class, they will be preferred over the generic version of the method.
Botz answer is 100% correct, here's a short explanation:
When you are writing a method (generic or not) and declaring the types of the parameters that the method takes you are defining a contract:
If you give me an object that knows how to do the set of things that
Type T knows how to do I can deliver either 'a': a return value of the
type I declare, or 'b': some sort of behavior that uses that type.
If you try and give it more than one type at a time (by having an or) or try to get it to return a value that might be more than one type that contract gets fuzzy:
If you give me an object that knows how to jump rope or knows how to calculate pi
to the 15th digit I'll return either an object that can go fishing or maybe mix
concrete.
The problem is that when you get into the method you have no idea if they've given you an IJumpRope or a PiFactory. Furthermore, when you go ahead and use the method (assuming that you've gotten it to magically compile) you're not really sure if you have a Fisher or an AbstractConcreteMixer. Basically it makes the whole thing way more confusing.
The solution to your problem is one of two possiblities:
Define more than one method that defines each possible transformation, behavior, or whatever. That's Botz's answer. In the programming world this is referred to as Overloading the method.
Define a base class or interface that knows how to do all the things that you need for the method and have one method take just that type. This may involve wrapping up a string and Exception in a small class to define how you plan on mapping them to the implementation, but then everything is super clear and easy to read. I could come, four years from now and read your code and easily understand what's going on.
Which you choose depends on how complicated choice 1 and 2 would be and how extensible it needs to be.
So for your specific situation I'm going to imagine you're just pulling out a message or something from the exception:
public interface IHasMessage
{
string GetMessage();
}
public void test(string a, IHasMessage arg)
{
//Use message
}
Now all you need are methods that transform a string and an Exception to an IHasMessage. Very easy.
If ChildClass means it is derived from ParentClass, you may just write the following to accept both ParentClass and ChildClass;
public void test<T>(string a, T arg) where T: ParentClass
{
//do something
}
On the otherhand, if you want to use two different types with no inheritance relation between them, you should consider the types implementing the same interface;
public interface ICommonInterface
{
string SomeCommonProperty { get; set; }
}
public class AA : ICommonInterface
{
public string SomeCommonProperty
{
get;set;
}
}
public class BB : ICommonInterface
{
public string SomeCommonProperty
{
get;
set;
}
}
then you can write your generic function as;
public void Test<T>(string a, T arg) where T : ICommonInterface
{
//do something
}
As old as this question is I still get random upvotes on my explanation above. The explanation still stands perfectly fine as it is, but I'm going to answer a second time with a type that's served me well as a substitute for union types (the strongly-typed answer to the question that's not directly supported by C# as is).
using System;
using System.Diagnostics;
namespace Union {
[DebuggerDisplay("{currType}: {ToString()}")]
public struct Either<TP, TA> {
enum CurrType {
Neither = 0,
Primary,
Alternate,
}
private readonly CurrType currType;
private readonly TP primary;
private readonly TA alternate;
public bool IsNeither => currType == CurrType.Neither;
public bool IsPrimary => currType == CurrType.Primary;
public bool IsAlternate => currType == CurrType.Alternate;
public static implicit operator Either<TP, TA>(TP val) => new Either<TP, TA>(val);
public static implicit operator Either<TP, TA>(TA val) => new Either<TP, TA>(val);
public static implicit operator TP(Either<TP, TA> #this) => #this.Primary;
public static implicit operator TA(Either<TP, TA> #this) => #this.Alternate;
public override string ToString() {
string description = IsNeither ? "" :
$": {(IsPrimary ? typeof(TP).Name : typeof(TA).Name)}";
return $"{currType.ToString("")}{description}";
}
public Either(TP val) {
currType = CurrType.Primary;
primary = val;
alternate = default(TA);
}
public Either(TA val) {
currType = CurrType.Alternate;
alternate = val;
primary = default(TP);
}
public TP Primary {
get {
Validate(CurrType.Primary);
return primary;
}
}
public TA Alternate {
get {
Validate(CurrType.Alternate);
return alternate;
}
}
private void Validate(CurrType desiredType) {
if (desiredType != currType) {
throw new InvalidOperationException($"Attempting to get {desiredType} when {currType} is set");
}
}
}
}
The above class represents a type that can be either TP or TA. You can use it as such (the types refer back to my original answer):
// ...
public static Either<FishingBot, ConcreteMixer> DemoFunc(Either<JumpRope, PiCalculator> arg) {
if (arg.IsPrimary) {
return new FishingBot(arg.Primary);
}
return new ConcreteMixer(arg.Secondary);
}
// elsewhere:
var fishBotOrConcreteMixer = DemoFunc(new JumpRope());
var fishBotOrConcreteMixer = DemoFunc(new PiCalculator());
Important Notes:
You'll get runtime errors if you don't check IsPrimary first.
You can check any of IsNeither IsPrimary or IsAlternate.
You can access the value through Primary and Alternate
There are implicit converters between TP/TA and Either<TP, TA> to allow you to pass either the values or an Either anywhere where one is expected. If you do pass an Either where a TA or TP is expected, but the Either contains the wrong type of value you'll get a runtime error.
I typically use this where I want a method to return either a result or an error. It really cleans up that style code. I also very occasionally (rarely) use this as a replacement for method overloads. Realistically this is a very poor substitute for such an overload.
Reading this, I learned it was possible to allow a method to accept parameters of multiple types by making it a generic method. In the example, the following code is used with a type constraint to ensure "U" is an IEnumerable<T>.
public T DoSomething<U, T>(U arg) where U : IEnumerable<T>
{
return arg.First();
}
I found some more code which allowed adding multiple type constraints, such as:
public void test<T>(string a, T arg) where T: ParentClass, ChildClass
{
//do something
}
However, this code appears to enforce that arg must be both a type of ParentClass and ChildClass. What I want to do is say that arg could be a type of ParentClass or ChildClass in the following manner:
public void test<T>(string a, T arg) where T: string OR Exception
{
//do something
}
Your help is appreciated as always!
That is not possible. You can, however, define overloads for specific types:
public void test(string a, string arg);
public void test(string a, Exception arg);
If those are part of a generic class, they will be preferred over the generic version of the method.
Botz answer is 100% correct, here's a short explanation:
When you are writing a method (generic or not) and declaring the types of the parameters that the method takes you are defining a contract:
If you give me an object that knows how to do the set of things that
Type T knows how to do I can deliver either 'a': a return value of the
type I declare, or 'b': some sort of behavior that uses that type.
If you try and give it more than one type at a time (by having an or) or try to get it to return a value that might be more than one type that contract gets fuzzy:
If you give me an object that knows how to jump rope or knows how to calculate pi
to the 15th digit I'll return either an object that can go fishing or maybe mix
concrete.
The problem is that when you get into the method you have no idea if they've given you an IJumpRope or a PiFactory. Furthermore, when you go ahead and use the method (assuming that you've gotten it to magically compile) you're not really sure if you have a Fisher or an AbstractConcreteMixer. Basically it makes the whole thing way more confusing.
The solution to your problem is one of two possiblities:
Define more than one method that defines each possible transformation, behavior, or whatever. That's Botz's answer. In the programming world this is referred to as Overloading the method.
Define a base class or interface that knows how to do all the things that you need for the method and have one method take just that type. This may involve wrapping up a string and Exception in a small class to define how you plan on mapping them to the implementation, but then everything is super clear and easy to read. I could come, four years from now and read your code and easily understand what's going on.
Which you choose depends on how complicated choice 1 and 2 would be and how extensible it needs to be.
So for your specific situation I'm going to imagine you're just pulling out a message or something from the exception:
public interface IHasMessage
{
string GetMessage();
}
public void test(string a, IHasMessage arg)
{
//Use message
}
Now all you need are methods that transform a string and an Exception to an IHasMessage. Very easy.
If ChildClass means it is derived from ParentClass, you may just write the following to accept both ParentClass and ChildClass;
public void test<T>(string a, T arg) where T: ParentClass
{
//do something
}
On the otherhand, if you want to use two different types with no inheritance relation between them, you should consider the types implementing the same interface;
public interface ICommonInterface
{
string SomeCommonProperty { get; set; }
}
public class AA : ICommonInterface
{
public string SomeCommonProperty
{
get;set;
}
}
public class BB : ICommonInterface
{
public string SomeCommonProperty
{
get;
set;
}
}
then you can write your generic function as;
public void Test<T>(string a, T arg) where T : ICommonInterface
{
//do something
}
As old as this question is I still get random upvotes on my explanation above. The explanation still stands perfectly fine as it is, but I'm going to answer a second time with a type that's served me well as a substitute for union types (the strongly-typed answer to the question that's not directly supported by C# as is).
using System;
using System.Diagnostics;
namespace Union {
[DebuggerDisplay("{currType}: {ToString()}")]
public struct Either<TP, TA> {
enum CurrType {
Neither = 0,
Primary,
Alternate,
}
private readonly CurrType currType;
private readonly TP primary;
private readonly TA alternate;
public bool IsNeither => currType == CurrType.Neither;
public bool IsPrimary => currType == CurrType.Primary;
public bool IsAlternate => currType == CurrType.Alternate;
public static implicit operator Either<TP, TA>(TP val) => new Either<TP, TA>(val);
public static implicit operator Either<TP, TA>(TA val) => new Either<TP, TA>(val);
public static implicit operator TP(Either<TP, TA> #this) => #this.Primary;
public static implicit operator TA(Either<TP, TA> #this) => #this.Alternate;
public override string ToString() {
string description = IsNeither ? "" :
$": {(IsPrimary ? typeof(TP).Name : typeof(TA).Name)}";
return $"{currType.ToString("")}{description}";
}
public Either(TP val) {
currType = CurrType.Primary;
primary = val;
alternate = default(TA);
}
public Either(TA val) {
currType = CurrType.Alternate;
alternate = val;
primary = default(TP);
}
public TP Primary {
get {
Validate(CurrType.Primary);
return primary;
}
}
public TA Alternate {
get {
Validate(CurrType.Alternate);
return alternate;
}
}
private void Validate(CurrType desiredType) {
if (desiredType != currType) {
throw new InvalidOperationException($"Attempting to get {desiredType} when {currType} is set");
}
}
}
}
The above class represents a type that can be either TP or TA. You can use it as such (the types refer back to my original answer):
// ...
public static Either<FishingBot, ConcreteMixer> DemoFunc(Either<JumpRope, PiCalculator> arg) {
if (arg.IsPrimary) {
return new FishingBot(arg.Primary);
}
return new ConcreteMixer(arg.Secondary);
}
// elsewhere:
var fishBotOrConcreteMixer = DemoFunc(new JumpRope());
var fishBotOrConcreteMixer = DemoFunc(new PiCalculator());
Important Notes:
You'll get runtime errors if you don't check IsPrimary first.
You can check any of IsNeither IsPrimary or IsAlternate.
You can access the value through Primary and Alternate
There are implicit converters between TP/TA and Either<TP, TA> to allow you to pass either the values or an Either anywhere where one is expected. If you do pass an Either where a TA or TP is expected, but the Either contains the wrong type of value you'll get a runtime error.
I typically use this where I want a method to return either a result or an error. It really cleans up that style code. I also very occasionally (rarely) use this as a replacement for method overloads. Realistically this is a very poor substitute for such an overload.
I am creating the wrapper POCO classes for ENUM in Entity Framework 4 as mentioned here. I have created the wrapper for the enum as follows
public class PriorityWrapper
{
private gender _t;
public int Value
{
get
{
return (int)_t;
}
set
{
_t = (gender)value;
}
}
public gender EnumValue
{
get
{
return _t;
}
set
{
_t = value;
}
}
public static implicit operator PriorityWrapper(gender p)
{
return new PriorityWrapper { EnumValue = p };
}
public static implicit operator gender(PriorityWrapper pw)
{
if (pw == null) return gender.Male;
else return pw.EnumValue;
}
}
But I also have other ENUM apart from gender as mentioned above. Can I use generics here so I can use the same code for all ENUM occurrences.
I am new to generics, so need help from experts.
You cannot use enums as generic constraints, instead you can use.
public class EnumWrapper<T>
{
public static int Num = 1;
private T _t;
public T EnumValue
{
get
{
return _t;
}
set
{
_t = value;
}
}
public void Assign<U>(U inn) where U : struct, T
{
if (typeof(T).IsEnum)
{
EnumValue = inn;
}
}
}
and invoke it like this
var agen = new EnumWrapper<gender>();
gender g=new gender() ;
agen.Assign (g);
EDIT: Assign() is a dummy method. My intention was to show how to use enum as generic constraint.
It is not possible to have generic conversion operators. So, there can't be exact generic equivalent for above code. Besides, one cannot mention enum as generic type constraint, so casting within property implementation is also not possible (or may need some other constraint (possibly interface) to work that may result in boxing/unboxing). In short, IMO, having generic solution with reasonable performance may not be feasible.
I would suggest that you try using code generation (look at T4 templates) for creating your wrapper classes. T4 is pretty simple - refer here for few links: http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx
I'm trying to do this:
public interface IVirtualInterface{ }
public interface IFabricationInfo : IVirtualInterface
{
int Type { get; set; }
int Requirement { get; set; }
}
public interface ICoatingInfo : IVirtualInterface
{
int Type { get; set; }
int Requirement { get; set; }
}
public class FabInfo : IFabricationInfo
{
public int Requirement
{
get { return 1; }
set { }
}
public int Type
{
get {return 1;}
set{}
}
}
public class CoatInfo : ICoatingInfo
{
public int Type
{
get { return 1; }
set { }
}
public int Requirement
{
get { return 1; }
set { }
}
}
public class BusinessObj
{
public T VirtualInterface<T>() where T : IVirtualInterface
{
Type targetInterface = typeof(T);
if (targetInterface.IsAssignableFrom(typeof(IFabricationInfo)))
{
var oFI = new FabInfo();
return (T)oFI;
}
if (targetInterface.IsAssignableFrom(typeof(ICoatingInfo)))
{
var oCI = new CoatInfo();
return (T)oCI;
}
return default(T);
}
}
But getting a compiler error: Canot convert type 'GenericIntf.FabInfo' to T
How do I fix this?
thanks
Sunit
Assuming all IVirtualInterface implementations will have a default constructor (as in your example), you can do this instead:
public T VirtualInterface<T>() where T : IVirtualInterface, new()
{
return new T();
}
Simples!
EDIT:
Exactly what you're trying to achieve is difficult to determine from the code you've posted. Why isn't VirtualInterface static (implies all business objects inherit this method which seems odd)? If you need o be able to parameterised constructors for your IVirtualInterface implementations, where would those parameter values come from (you're not passing any into the VirtualInterface method)?
If you just want to avoid cluttering up intellisense (a poor reason for trying something like this IMHO) but also want to maintain support for parameteried constructors, then how about this:
public T VirtualInterface<T>(Func<T> constructor) where T : IVirtualInterface
{
return constructor();
}
With usage:
IFabricationInfo fabInfo =
new BusinessObj().VirtualInterface<IFabricationInfo>(() => new FabInfo());
Overall though, and without enough information to make a solid judgement, I'd have to say that this smells.
The fact that T and FabInfo both implement IVirtualInterface does not mean you can perform a cast between the two types. For example if T is CoatInfo, then it is not compatible type with FabInfo.
Interfaces allow you to treat different objects as similar types based on the methods they provide. However, this does not mean that you can perform casts between these two types as their actual implementation can vary greatly.
Edit: After re-reading your method again, I see that you are checking the type first. The problem is that the compiler doesn't know you are performing that logic before you try to make that cast. If you are writing a generic method and are checking the type of T, you are likely misusing the concept of generics. See the other answers for the way you should be creating new instances of T.
You can get around this error by first casting to object before casting to T e.g.
return (T)(object)oFI;
and similarly for CoatInfo
However I think switching on a generic type is an abuse, since if you want a limited number of possible return values, you could make the options explicit e.g.
public IFabricationInfo GetFabricationInfo()
{
return new FabInfo();
}
Let's say I have a data object, but this object can hold one of several types of data.
class Foo
{
int intFoo;
double doubleFoo;
string stringFoo;
}
Now, I want to create an accessor. Some way to get at this data. Obviously, I could create multiple accessors:
public int GetIntFoo();
public double GetDoubleFoo();
public string GetStringFoo();
Or I could create multiple properties
public int IntFoo { get; set; }
public double DoubleFoo { get; set; }
public string StringFoo { get; set; }
I don't that this is a very good design. It requires the client code to be more concerned about type than it should have to be. What's more, I really need only a single value for this class and the above would allow one of each type to be assigned at the same time. Not good.
One option is to use Generics.
class Foo<T>
{
public T TheFoo { get; set; }
}
However, this doesn't create a Foo, it creates a Foo<T>. A different type for each, so I can't really use them as the same type.
I could derive Foo<T> from FooBase, then treat all of them as FooBase's, but then i'm back in the problem of accessing the data.
A different Generics option is to use something like this:
class Foo
{
string stringRepresentationOfFoo;
public T GetFoo<T>() { return /* code to convert string to type */ }
}
OF course the problem is that any kind of T could be passed, and frankly, it's a bit busy.
I could also just box the values and return an object, but then there is no type safety.
Ideally, I want to treat all Foo's the same, but I want type safety so that if there isn't a StringFoo, I can't even compile a reference to a StringFoo.
Foo foo = new Foo("Foo");
string sFoo = foo.Value; // succeeds.
Foo foo = new Foo(0);
int iFoo = foo.Value; // succeeds
string sFoo = foo.Value; // compile error
Perhaps this isn't even possible.. and I'll have to make some compromises, but maybe i'm missing something.
Any ideas?
EDIT:
Ok, so as daniel points out, the compile time checking of a runtime type is not practical.
What is my best option for doing what I want to do here? Namely, Treat all Foo's the same, but still have a relatively sane access mechanism?
EDIT2:
I don't want to convert the value to different types. I want to return the correct type for the value. That is, if it's a double, I don't want to return an int.
How about passing in the variable as a parameter to the get? Like this:
int i = foo.get(i);
Then in your class, you'd have something like:
public int get(int p) {
if(this.type != INTEGER) throw new RuntimeException("Data type mismatch");
return this.intVal;
}
public float get(float p) {
if(this.type != FLOAT) throw new RuntimeException("Data type mismatch");
return this.floatVal;
}
This sort of turns the type checking inside-out: instead of checking what type foo holds, you have foo check what type you want. If it can give you that type, it does, or else it throws a runtime exception.
I don't think this could work (giving you the compiler error you want)
What would you want this to do:
Foo bar = (new Random()).Next(2) == 0 ? new Foo("bar") : new Foo(1);
int baz = bar.Value;
Is that a compiler error?
I think "treat them all the same" (at least the way you've described it) and "compile time error" are going to be mutually exclusive.
In any case, I think the "best way" is going to be a compromise between generics and inheritance. You can define a Foo<T> that is a subclass of Foo; then you can still have collections of Foo.
abstract public class Foo
{
// Common implementation
abstract public object ObjectValue { get; }
}
public class Foo<T> : Foo
{
public Foo(T initialValue)
{
Value = initialValue;
}
public T Value { get; set; }
public object ObjectValue
{
get { return Value; }
}
}
Many systems use a helper methods to return the alternate types just as the .net frameworks base object has the ToString() method
Choose which is the best base type for each of your object and provide To methods for other cases
e.g.
class Foo{
public Int32 Value { get; set; }
public Byte ToByte() { return Convert.ToByte(Value); }
public Double ToDouble() { return (Double)Value; }
public new String ToString() { return Value.ToString("#,###"); }
}
One thing is to store any type in your internal state of the class, and another is to expose it externally. When you write a class, you are actually declaring a contract for its behavior. The way you write it will influence greatly how client code will look like when using the class.
For example, by implementing the IConvertible interface you state that your type can be converted to any CLR type as an equivalent value.
I have also seen implementations where a Value class was used to store results of calculations, results that could represent either a string, double, int or boolean. But, the problem was that client code had to check a Value.Type property of an enum {String, Integer, Double, Boolean} and then either cast the Value.Value property (which was exposed externally by the Value class as an Object type) or use the specific ValueString, ValueDouble, ValueInt, ValueBoolean getters.
Why not just use string, double and int?
After info about collection: What about using object? You will have to check for types and such afterwards anyways. And to help you with that you can use the is and as operators. And the Enumerable.Cast Method, or even better, the Enumerable.OfType Method.
Actually, what is the purpose of this class? The biggest problem seems to be design breaking at least SRP (single responsibility principle).
Nonetheless, if I'm reading it correctly, you'd like to store some value in the container, pass the container to client and type-safely retrieve the value.
With this approach, you can use your proposal, i.e.
namespace Project1 {
public class Class1 {
static int Main(string[] args) {
Foo a = new Foo();
a.SetValue(4);
Console.WriteLine(a.GetValue<int>());
Foo b = new Foo();
a.SetValue("String");
Console.WriteLine(a.GetValue<string>());
Console.ReadLine();
return 0;
}
}
class Foo {
private object value; // watch out for boxing here!
public void SetValue(object value) {
this.value = value;
}
public T GetValue<T>() {
object val = this.value;
if (val == null) { return default(T); } // or throw if you prefer
try {
return (T)val;
}
catch (Exception) {
return default(T);
// cast failed, return default(T) or throw
}
}
}
}
However, in that case why not simply pass data as object and cast by yourself?
Depending on your needs, you may also try "PHP in C#":
namespace Project1 {
public class Class1 {
static int Main(string[] args) {
MyInt a = 1;
MyInt b = "2";
Console.WriteLine(a + b); // writes 3
Console.ReadLine();
return 0;
}
}
class MyInt {
private int value;
public static implicit operator int(MyInt container) {
return container.value;
}
public static implicit operator MyInt(int value) {
MyInt myInt = new MyInt();
myInt.value = value;
return myInt ;
}
public static implicit operator MyInt(string stringedInt) {
MyInt myInt = new MyInt();
myInt.value = int.Parse(stringedInt);
return myInt;
}
}
}
I'm sorry, I just don't buy your premise. If the data all have the same purpose, then they should all have the same type. Consider a class that's meant to hold the current temperature, as returned by one of several web services. All the services return the temperature in Centigrade. But one returns as an int, one returns as a double, and one returns it as a string.
It's not three different types - it's one type - double. You would simply need to convert the non-double returns into double, which is what the temperature is (or maybe float).
In general, if you have multiple representations of one thing, then it's still one thing, not multiple things. Convert the multiple representations into one.