Required Suggestions: An alternative to overloading the has and how operators in .NET.

I hope that this question is not considered too subjective - I really do not expect a final answer, but I hope that all opinions, at least, will help me form my own.

I am implementing a custom type system, which is a superset of the classical OOP type system. In this type system, instances of objects can be combined at run time to form new instances, while retaining individual identifiers.

This code:

var p = new Person();
var pa = new Partner(p);

... leads to a single, combined object, with "p" and "pa" representing different OOP-compatible representations. IOW, a change in the value of a property in one of the views is immediately reflected in any other view that also contains this property.

Everything works fine and well, but there are no two key APIs for type queries. I would really like to write this code:

if (p is Partner)
{
    (p as Partner).SomePartnerProperty = "...";
}

This, of course, does not work, because the behavior of the "is" and "as" statements cannot be overloaded / extended outside the .NET OOP rules. However, I still need this function in my type system.

My first thought was to use common extension methods that would attach to all instances of my type system:

public static bool Is<T>(this BaseType target) where T : BaseType { ... }
public static T As<T>(this BaseType target) where T : BaseType { ... }

, , , :

if (p.Is<Partner>())
{
    p.As<Partner>().SomePartnerProperty = "...";
}

- , API, ?

, ?

. , ... , : Identity or Role. , , Person - Identity ( ), Partner - ( , - -). , Identity, ​​ Identity (, Contact, ). , , -, , Identity (, Person, Company, Bank ..).

+5
8

.

( ) :

p.IsType(typeHere)
p.IsPartner()

- :

p.ToPartner()

( ), .

+1

, , mixin # - mixins #?. , , mixin, , /.

+1

( , ), . explicit implicit ( , ), "gotchas", , .

0

# , " " (, x.Is<T>()) ( , ).

F #, , .

match p with
| IsPartner pa -> DoPartnerStuff(pa)
| _ -> JustPersonStuff(p)
0

- - ...

class Role {
    public Role(Person p) { p.liRoles.Add(this); }
}
class Partner : Role {
    public Partner(Person p) : base(p) {}
}
class Person { 
    List<IRole> liRoles;
    public T As<T>() { 
        foreach(IRole r in liRoles){ if r is T return r; }
        return null;
    }
    public bool Is<T>() { return As<T>() != null; }
}
var p = new Person();
var pa = new Partner(p);

-

if (p is Partner)
   (p as Partner).PartnerMethod();

, ;)

0

... , OO ( )

interface IPartner {...}
interface IPerson {...}
interface ICompany {...}

class Person : IPerson {...}
class PersonPartner : Person, IPartner {...}
class Company : ICompany {...}
class CompanyPartner : Company, IPartner {...}

, , ...

0

#. , , , , ( , ). Perl 6, Is Does. As .

, , :

var p = new Person(); 
var pa = new Partner(p); 

It does not look like they are pointing to the same instance. Now, borrowing from Scala , maybe something like this?

var p = new Person(); 
var pa = p.With<Partner>(); 

In any case, have you completed your API? Is this an open source?

0
source

It seems to me that Partnerit is not Person, but it Partnerdoes Person. For me, the interface would make sense like

var p = new Person();
var pa = new Partner(p);

pa.SomePartnerProperty = "...";
pa.Person.SomePersonProperty = "...";
-1
source

All Articles