dhakehurst

I am trying to define a class library.

The classes all implement an interface.

In addition I want to provide implicit conversion and operators for the defined types.

This is most easily illustrated if I use a simple example, such as providing my own

String class - MyString. (I actually want to do this with a a variety of different classes, the use

of MyString is simply a way to illustrate the example.)

The following code ilustrates what I want to do, and what I assumed would be correct.

Clearly it does not work, and is not allowed by the rules of C# w.r.t interfaces.

I would appreciate any solutions, work arounds, or info on why should just not do this!

If I do this without the use of an interface, there is no problem, it all works as is expected.

However, I want an interface, and I want users of my class library to use the interfaces, not

the classes.

static void Main(string[] args)
{
MyString s1 = "hello";

MyString s2 = " world";

MyString s3 = s1 + s2 ;

s3.myStrFunc();

}

namespace MySpace {

public interface MyString {

static bool operator==(MyString s1, MyString s2);

static bool operator!=(MyString s1, MyString s2);

static String operator+(MyString s1, MyString s2);

static implicit operator string(MyString s);

static implicit operator MyString(string s);

void myStrFunc();

}

public class MyStringImpl : MyString {

public void myStrFunc() { ... }

public static bool operator==(MyString s1, MyString s2) { ... }

public static bool operator!=(MyString s1, MyString s2) { ... }

public static String operator+(MyString s1, MyString s2) { ... }

public static implicit operator string(MyString s) { ... }

public static implicit operator MyString(string s) { ... }

}

}



Re: Visual C# Language Interfaces, Operators and Conversions

ARK88

Syntactically this isn't going to meet your criteria, but what about declaring methods with names like "IsEqual", "IsNotEqual", "Addition", etc... I don't think this is extremely far-fetched as the definition of "System.Object" actually has a method named "Equals" (which can be overriden). Just a thought...



Re: Visual C# Language Interfaces, Operators and Conversions

dhakehurst

Yes I could define a collection of methods such as you suggest.

(In fact, I have provided the same library in Java, using just that mechanism.)

However, it would be far nicer for the users of the library if the C# version could make use of the

(supposed) C# facility for overloading operators!





Re: Visual C# Language Interfaces, Operators and Conversions

sirjis

Alternatively, you could use an abstract base class, which does allow static methods and operators.

This would only be a potential design issue if you had some class that should expose a string interface, but isn't actually a string (or it already inherits from something else).





Re: Visual C# Language Interfaces, Operators and Conversions

dhakehurst

Abstract base class won't work in the real situation as I have some multiple inheritance

in the type hierachy, which needs to be supported using interfaces.





Re: Visual C# Language Interfaces, Operators and Conversions

Figo Fei - MSFT

Hi, dhakehurst

Since the MyStringImpl class inherits interface MyString which define operator overloads emplicit and implicit.

We should first implement the interface, (it seems that you have done so far).

However, we can only use class instance to do the casting instead of a single interface definition s1, s2 or s3.

We must create an instance of MyStringImpl to do so.

Something like

Code Snippet
public class MyStringImpl
{
public MyStringImpl()
{ str = ""; }
public MyStringImpl(string s)
{ str = s; }
public void myStrFunc() { Console.WriteLine(this.str); }
public string str;
public static MyStringImpl operator +(MyStringImpl s1, MyStringImpl s2) { return new MyStringImpl(s1.str + s2.str); }
public static implicit operator string(MyStringImpl s) { return s.str; }
public static implicit operator MyStringImpl(string s) { return new MyStringImpl(s); }
}
static void Main(string[] args)
{
MyStringImpl s1 = "hello1";
MyStringImpl s2 = "hello2";
MyStringImpl s3 = s1 + s2;
s3.myStrFunc();
//Console.ReadLine();
}

If it doesn't meet your needs, you'd show your full designing idea to see whether we can achieve this by Generics in C#.

Thanks






Re: Visual C# Language Interfaces, Operators and Conversions

dhakehurst

The point being, I want to use an interface, not a class.

That way , I can substitute the implementation of the interface with an alternative, if I want to.

i.e. I want to use the class via its interface, as I said in the first posting:-

static void Main(string[] args)
{
MyString s1 = "hello1";
MyString s2 = "hello2";
MyString s3 = s1 + s2;
s3.myStrFunc();
}

in Java I had to live with something like :

static void main(String[] args) {

MyString s1 = Factory.create("hello");

MyString s2 = Factory.create(" world");

MyString s3 = s1.plus(s2);

s3.myStrFunc();

}

which of course I can do in C# as well, but I had hoped to do something better, using the operators and conversion

features available.

I fully appreciate the programming practice of using interfaces, I don't want to take a step backwards

just so that I can use operators and conversions.





Re: Visual C# Language Interfaces, Operators and Conversions

Figo Fei - MSFT

dhakehurst wrote:

static void Main(string[] args)
{
MyString s1 = "hello";

MyString s2 = " world";

MyString s3 = s1 + s2 ;

s3.myStrFunc();

}

namespace MySpace {

public interface MyString {

static bool operator==(MyString s1, MyString s2);

static bool operator!=(MyString s1, MyString s2);

static String operator+(MyString s1, MyString s2);

static implicit operator string(MyString s);

static implicit operator MyString(string s);

void myStrFunc();

}

public class MyStringImpl : MyString {

public void myStrFunc() { ... }

public static bool operator==(MyString s1, MyString s2) { ... }

public static bool operator!=(MyString s1, MyString s2) { ... }

public static String operator+(MyString s1, MyString s2) { ... }

public static implicit operator string(MyString s) { ... }

public static implicit operator MyString(string s) { ... }

}

}

First, from syntax aspect, interface doesn't allow static methods as its members.

The reason is that interfaces are about defining a contract of method names that an *instance* has to support, statics aren't instance level methods but class level.

Consider the following assumption:

If we have another class named MyStringImpl2 which also inherits MyString interface, in this case if we add two instances which meet MyString interface, which class would it be referring to, MyStringImpl or MyStringImpl2

Thanks






Re: Visual C# Language Interfaces, Operators and Conversions

dhakehurst

I fully accept and understand that interfaces are contracts that a class is supposed to fulfil.

Another way of understanding this is that an interface defines a type, and a class provides

a template for constructing an object that coresponds to such a type

(if the class implements the interface).

Conceptually I don't see why we should not be able to define as part of a contract for a class

(i.e. an interface) that it must implement certain operators.

I realise that putting static things in an interface is not a leagal C# way to do this,

(though one could argue a semantics for static methods in an inferface).

>"If we have another class named MyStringImpl2"

exactly, I want to be able to have another class that implements the same interface,

and I want that interface to specify that the classes that implement it must implement

certain converters and operators.

I don't mind if the converters and operators are static or non-static. However,

if there turn out to be multiple static methods that are applicable in a given

namespace/environment then I would expect a compiler error - as is the case for non-static methods.

> "which class would it be referring to, MyStringImpl or MyStringImpl2"

the whole point is that it shouldn't matter, they both implement the same interface !





Re: Visual C# Language Interfaces, Operators and Conversions

Figo Fei - MSFT

dhakehurst wrote:

> "which class would it be referring to, MyStringImpl or MyStringImpl2"

the whole point is that it shouldn't matter, they both implement the same interface !

It doesn't matter you, but does matter the implementation, since each class can implement the operator in its own way!

So we have no idea which implementation should apply, right

I guess could we modify the design pattern to do so, through inheritance or something, however first the design should be reasonable and easy to be understood. Do you agree with me Smile

We may define a father class to implement operators that the child classes can inherit from it... ...

Thanks






Re: Visual C# Language Interfaces, Operators and Conversions

dhakehurst

Ok let us assume we have these two classes MyStringImpl and MyStringImpl2 that both implement the MyString

interface.

What would be the problem with enabling/allowing the following :-

Code Snippet

class MyStringImpl : MyString

{

public static bool operator==(MyString s1, MyString s2)

{

...

}

}

-----------------------------------

class MyStringImpl2 : MyString

{

public static bool operator==(MyString s1, MyString s2)

{

...

}

}

-----------------------------------

using MyNamespace.MyStringImpl;

static void Main(string[] args)
{
MyString s1 = "hello";

MyString s2 = " world";

bool b = (s1 == s2);

}

as the operator is defined to be between objects that conform to the type MyString rather than the class,

it doesn't matter whether they are implemented using MyStringImpl or MyStringImpl2.

we know which implementation will be used, because the 'using' statement defines the environment of available methods/types.





Re: Visual C# Language Interfaces, Operators and Conversions

Figo Fei - MSFT

dhakehurst wrote:

Ok let us assume we have these two classes MyStringImpl and MyStringImpl2 that both implement the MyString

interface.

What would be the problem with enabling/allowing the following :-

Code Snippet

class MyStringImpl : MyString

{

public static bool operator==(MyString s1, MyString s2)

{

...

}

}

-----------------------------------

class MyStringImpl2 : MyString

{

public static bool operator==(MyString s1, MyString s2)

{

...

}

}

-----------------------------------

using MyNamespace.MyStringImpl;

static void Main(string[] args)
{
MyString s1 = "hello";

MyString s2 = " world";

bool b = (s1 == s2);

}

as the operator is defined to be between objects that conform to the type MyString rather than the class,

it doesn't matter whether they are implemented using MyStringImpl or MyStringImpl2.

we know which implementation will be used, because the 'using' statement defines the environment of available methods/types.

Hi,

Since you attempt to compare all the instances who inherit the MyString, why not make it a class instead of an interface, to give MyStringImpl and MyStringImpl2 an uniform prototype

So, I would suggest to define a class being MyStringImpl and MyStringImpl2 's father(named "MyString" for example), and implement the operation in the father class. (Alternatively, you can define virtual one for child class to override, if you want)

Thanks






Re: Visual C# Language Interfaces, Operators and Conversions

dhakehurst

That doesn't help w.r.t. using the class via an interface.

I want to remove as far as possible, users of the MyString interface from the implementation(s).

(remember, 'MyString' is just illustrating the issue in general.)





Re: Visual C# Language Interfaces, Operators and Conversions

Figo Fei - MSFT

In such a case, I don't think interface sould be applied.

Good thing is always being used in a proper place.

Thanks






Re: Visual C# Language Interfaces, Operators and Conversions

EBF_2

My understanding of the problem with overloading operator+ on an interface is that MS doesn't allow it for *any* technical or practical reason, but rather to enforce the CLS 'contract' amongst it's language that do not (ie, VB.NET) support operator overloading.

That said, I have no idea what the fix is, and any attempt to use a class to get functionality that naturally belongs in the interface will feel like a tortured hack.

Thanks,
Eric