I've got some weird behaviour in Moq 4.2. When I make a mock of an abstract class which implements an interface which defines properties, I can access the properties just fine, as long as the instance is the original type. If I cast that instance to the underlying interface, the properties return default values.
See below for an example. Anyone have a solution to this?
In the example below, doing foo.As<IFoo>() does not help.
public interface IFoo { string Thingy { get; } }
public abstract class Foo : IFoo
{
public Foo() { Thingy = "Howdy"; }
public string Thingy { get; }
}
public class Test
{
public void DoIt()
{
var foo = new Mock<Foo>();
Console.WriteLine(foo.Object.Thingy); // prints "Howdy"
Console.WriteLine((foo.Object as IFoo).Thingy); // prints nothing
}
}
Mock - generates a proxy of some object with its own implementation.
proxyImpl1 : IFoo { string Thingy => default }
call Thingy return proxied property
proxyImpl : Foo {nothing, since the parent object does not contain virtual methods} call Thingy return parent non-overrided property.
POCO works the same way in EF
Related
Is there a neat way to specify that a class must contain a factory method that returns the same kind of object as the class that overrides the abstract method? (Edit: Or as Johnathon Sullinger more eloquently puts it, [...] have a base class enforce a child class to implement a method that returns an instance of the child class itself, and not allow returning an instance of any other Type that inherits from the base class.)
For example, if I've got two classes, SimpleFoo : BaseFoo and FancyFoo : BaseFoo, can I define an abstract factory method public TFoo WithSomeProp(SomeProp prop) where TFoo is a type parameter that is somehow fixed by the abstract method definition to the particular class that overrides it?
I had hopes of compile-time guarantees that either
a concrete WithSomeProp method definition in SomeFoo : BaseFoo will only be able to produce SomeFoos. If static abstract method definitions were legal, perhaps the following (pseudo-syntax) method extension best expresses this need:
public static abstract TFoo WithSomeProp<TFoo>(this TFoo source, SomeProp prop)
where TFoo : BaseFoo;
I don't think this is possible in C#.
or at least some way to parameterize the return type in an abstract method, e.g.
public abstract TFoo WithSomeProp<TFoo>(SomeProp prop)
where TFoo : BaseFoo;
This wouldn't prevent FancyFoo.WithSomeProp from returning SimpleFoos, but ok.
This abstract method itself seems to work, but my concrete definition then fails:
public override SimpleFoo WithSomeProp(SomeProp prop)
{
return new SimpleFoo(this.SomeOtherProp, ..., prop);
}
with the warning
no suitable method found to override
It appears to me that specifying type parameters in an abstract method does not allow fixing them in the overrides of those definitions, but rather it specifies that "A method with a type parameter should exist".
For now I simply have public abstract BaseFoo WithSomeProp(SomeProp prop);.
It sounds like what you want to do, is have a base class enforce a child class to implement a method that returns an instance of the child class itself, and not allow returning an instance of any other Type that inherits from the base class. Unfortunately, to the best of my knowledge, that is not something you can do.
You can however force the child-class to specify what it's Type is to the base class, so that the base class can then enforce that the return value must be the Type specified by the child-class.
For instance, given a base class called BaseFactory, and BaseFactory<T>, we can create an abstract class that requires children to specify to the parent, what type the creation method returns. We include a BaseFactory class so we can constrain T to only being children classes of BaseFactory.
EDIT
I'll leave the original answer below in the event that it helps, but after some thought, I think I've got a better solution for you.
You'll still need the base class to take a generic argument that defines what the child Type is. The difference now however is that the base class has a static creation method instead of instance methods. You can use this creation method to create a new instance of the child class, and optionally invoke a callback for configuring the property values on the new instance before you return it.
public abstract class BaseFactory { }
public abstract class BaseFactory<TImpl> : BaseFactory where TImpl : BaseFactory, new()
{
public static TImpl Create(Action<TImpl> itemConfiguration = null)
{
var child = new TImpl();
itemConfiguration?.Invoke(child);
return child;
}
}
You then just create your children classes normally, without worrying about overriding any methods.
public class Foo : BaseFactory<Foo>
{
public bool IsCompleted { get; set; }
public int Percentage { get; set; }
public string Data { get; set; }
}
public class Bar : BaseFactory<Bar>
{
public string Username { get; set; }
}
Then you would use the factory as-such.
class Program
{
static void Main(string[] args)
{
// Both work
Bar bar1 = Bar.Create();
Foo foo1 = Foo.Create();
// Won't compile because of different Types.
Bar bar2 = Foo.Create();
// Allows for configuring the properties
Bar bar3 = Bar.Create(instanceBar => instanceBar.Username = "Jane Done");
Foo foo2 = Foo.Create(instanceFoo =>
{
instanceFoo.IsCompleted = true;
instanceFoo.Percentage = 100;
instanceFoo.Data = "My work here is done.";
});
}
Original Answer
The BaseFactory<T> will be reponsible for creating a new instance of TImpl and giving it back.
public abstract class BaseFactory { }
public abstract class BaseFactory<TImpl> : BaseFactory where TImpl : BaseFactory
{
public abstract TImpl WithSomeProp();
}
Now, your child class can be created, and inherit from BaseFactory<T>, telling the base class that T represents itself. This means the child can only ever return itself.
public class Foo : BaseFactory<Foo>
{
public override Foo WithSomeProp()
{
return new Foo();
}
}
public class Bar : BaseFactory<Bar>
{
public override Bar WithSomeProp()
{
return new Bar();
}
}
Then you would use it like:
class Program
{
static void Main(string[] args)
{
var obj1 = new Bar();
// Works
Bar obj2 = obj1.WithSomeProp();
// Won't compile because obj1 returns Bar.
Foo obj3 = obj1.WithSomeProp();
}
}
If you really want to make sure that the generic specified is the same as the owning Type, you could instead make WithSomeProp a protected method, so that children classes can only see it. Then, you create a public method on the base class that can do type checking.
public abstract class BaseFactory { }
public abstract class BaseFactory<TImpl> : BaseFactory where TImpl : BaseFactory
{
protected abstract TImpl WithSomeProp();
public TImpl Create()
{
Type myType = this.GetType();
if (typeof(TImpl) != myType)
{
throw new InvalidOperationException($"{myType.Name} can not create instances of itself because the generic argument it provided to the factory is of a different Type.");
}
return this.WithSomeProp();
}
}
public class Foo : BaseFactory<Foo>
{
protected override Foo WithSomeProp()
{
return new Foo();
}
}
public class Bar : BaseFactory<Bar>
{
protected override Bar WithSomeProp()
{
return new Bar();
}
}
class Program
{
static void Main(string[] args)
{
var obj1 = new Bar();
// Works
Bar obj2 = obj1.Create();
// Won't compile because obj1 returns Bar.
Foo obj3 = obj1.Create();
}
}
Now, if you create a child class that passes a different Type as T, the base class will catch it and throw an exception.
// Throws exception when BaseFactory.Create() is called, even though this compiles fine.
public class Bar : BaseFactory<Foo>
{
protected override Foo WithSomeProp()
{
return new Foo();
}
}
Not sure if this gets you what you wanted at least, but I think this will probably be the closest thing you can get.
Inspired by Johnathon Sullinger's fine answer, here is the code I ended with. (I added a theme.)
I passed the type parameter T along with the class definition and constrained that T : Base<T>.
BaseHyperLink.cs:
public abstract class BaseHyperLink<THyperLink> : Entity<int>
where THyperLink : BaseHyperLink<THyperLink>
{
protected BaseHyperLink(int? id, Uri hyperLink, ContentType contentType, DocumentType documentType)
: base(id)
{
this.HyperLink = hyperLink;
this.ContentType = contentType;
this.DocumentType = documentType;
}
public Uri HyperLink { get; }
public ContentType ContentType { get; }
public DocumentType DocumentType { get; }
public abstract THyperLink WithContentType(ContentType contentType);
}
SharedHyperLink.cs:
public sealed class SharedHyperLink : BaseHyperLink<SharedHyperLink>
{
public SharedHyperLink(int? id, Uri hyperLink, ContentType contentType, DocumentType documentType)
: base(id, hyperLink, contentType, documentType)
{
}
public override SharedHyperLink WithContentType(ContentType contentType)
{
return new SharedHyperLink(this.Id, contentType, this.DocumentType);
}
}
MarkedHyperLink.cs:
public sealed class MarkedHyperLink : BaseHyperLink<MarkedHyperLink>
{
public MarkedHyperLink(int? id, Uri hyperLink, ContentType contentType, DocumentType documentType, Mark mark)
: base(id, hyperLink, contentType, documentType)
{
this.Mark = mark;
}
public Mark Mark { get; }
public override MarkedHyperLink WithContentType(ContentType contentType)
{
return new MarkedHyperLink(this.Id, contentType, this.DocumentType, this.Mark);
}
}
I have a class Foo that has a field _customObject that must be initialized. I also have a class Bar that inherits from Foo:
public abstract class Foo
{
protected CustomObject _customObject;
public Foo()
{
// Do stuff
}
// Other methods that use _customObject
}
public class Bar : Foo
{
// Constructor and other methods
}
I can not initialize the object _customObject in Foo because every child inherited contains a different child of CustomObject, so it must be initialized in every child class:
public class Bar : Foo
{
public Bar()
{
_customObject = new CustomObjectInherited1();
}
}
public class Baz : Foo
{
public Baz()
{
_customObject = new CustomObjectInherited2();
}
}
Other people are going to implement new classes that inherit from Foo, so I was wondering if there is a way that an error in build time is shown, similar to when an abstract method is not implemented. If CustomObject is not initialized, a NullReferenceException will be thrown due to the use of the _customObject variable, ending in an application crash.
You can add a parameter to your Foo constructor:
public abstract class Foo
{
protected CustomObject _customObject;
public Foo(CustomObject obj)
{
// Do stuff
_customObject = obj;
}
// Other methods that use _customObject
}
Your derived classes will then be forced to call it, passing in a CustomObject, or something derived from it:
public class Bar : Foo
{
public Bar():base(new CustomObjectInherited1())
{
}
}
Not calling the base constructor will result in a compile time error. This doesn't entirely protect you, as someone could still pass null to the base constructor, but at least they'll have an explanation as to why they're getting a NullReferenceError at runtime.
You can force it by creating a abstract method which requires child classes to override it.
public abstract class Foo
{
protected abstract CustomObject CreateCustomObject();
}
public class Bar : Foo
{
protected override CustomObject CreateCustomObject()
{
return new BarCustomObject();
}
}
Or my favorite solution: Enforce it by generic constraints.
public abstract class Foo<T> : where T : CustomObject, new()
{
protected T _customObject;
public Foo()
{
this.CustomObject = new T();
}
}
public class Bar : Foo<BarCustomObject>
{
}
The answer provided by "James Thorpe" is correct (I've upvoted it already), but I wanted to share just another option here:
You could mark your class as abstract and introduce an abstract property instead of the "_customObject" field. That way, at least the first initializer will be forced to implement it. The downside is that you'll loose the enforcement on subsequent level subclasses:
public abstract class Foo
{
protected abstract CustomObject CustomObject {get; }
public Foo()
{
// Do stuff
}
// Other methods that use _customObject
}
public class Bar : Foo
{
// Constructor and other methods
protected override CustomObject CustomObject
{
get { return "X"; }
}
}
Also, with the first solution it's possible to validate the passed in value in the constructor - though, that'll be a runtime validation.
Say I have the following code:
class Foo: IFoo {
public string fooProp { get; set; }
}
interface IFoo {
string fooProp {get; set; }
}
Is it at all possible for there to be different behavior between:
Foo x = new Foo();
someMethod(x);
and:
IFoo x = new Foo();
someMethod(x);
?
I think it may differ. If somebody's used bad style of programming, i.e.:
public void someMethod(IFoo f)
{
if (f is Foo)
{
Foo f1 = (Foo)f;
//Do smth with unique Foo members
}
//Do anything with IFoo members
}
Yes, there is a difference if someMethod has different overloads for IFoo and Foo.
public void someMethod(Foo f)
{
// Overload 1
}
public void someMethod(IFoo f)
{
// Overload 2
}
Foo x = new Foo();
someMethod(x); // Matches overload 1
IFoo x = new Foo();
someMethod(x); // Matches overload 2
(I'm no expert) but in your first scenario, you would get access to everything in Class Foo. In the second scenario, you would only be able to access the IFoo members. So if Foo has additional methods (that aren't part of the interface), you will be able to access them in your first scenario but not the second.
I believe using the interface name instead of the class name is just another way to encapsulate data and only provide access to the interface members. For instance you could have Foo and Bar which both implements IFoo. You could add both of them to, say, a List.
There would never be any difference.
Remember, an interface is a contract. By deriving Foo from IFoo, you are implementing that contract.
In both cases, because Foo is an IFoo and adheres to the contract, the behaviour will always be the same.
Of course, how Foo implements that contract is anybodies guess. But the contract is adhered too by the signature of the interface.
If you have two interfaces and there is a common method name in each of them then the implementing class can implement the same method differently. The it depends how the method is called - via interface or not and via which interface.
See here for a similar question:
Inheritance from multiple interfaces with the same method name
Different bahavior can be, but inside someMethod.
Say you have
class Foo: IFoo {
public fooProp { get; set; }
}
interface IFoo {
fooProp {get; set; }
myCustomProp {get;set}
}
if you have
public void someMethod(Foo _foo){
_foo.myCustomProp; //CAN DO THIS, AS YOUR TYPE IS _FOO_
}
Which will not be possible to do in case when the parameter of the method is defined like.
public void someMethod(IFoo _foo){
_foo.myCustomProp; //NO SUCH METHOD INFO
}
unless you don't cast. So the difference is that decaring IFoo, to decalre generic access parameter, but get less "potential" in terms of data access, but get a huge potential in abstraction over types in your architecture.
So the difference will be only in regard of architecture and program workflow.
You could have an explicitly implemented interface in Foo.
class Foo: IFoo {
private string _fooprop;
private string _ifooprop;
public string fooProp
{
get {return "IFoo";}
set {_fooprop=value;}
}
string IFoo.fooProp
{
get {return "Foo";}
set {_ifooprop=value;}
}
}
interface IFoo {
string fooProp {get; set; }
}
with this, you will have:
IFoo foo1=new Foo();
Foo foo2=new Foo();
Console.WriteLine(foo1.fooProp); // Foo
Console.WriteLine(foo2.fooProp); // iFoo
It's possible if you explicitly implement IFoo:
public class Foo : IFoo
{
public string Prop
{
get { return "Hello Foo"; }
}
string IFoo.Prop
{
get { return "Hello IFoo"; }
}
}
public static void SomeMethod<T>(T foo) where T : IFoo
{
var prop = typeof(T).GetProperty("Prop");
Console.WriteLine(prop.GetValue(foo));
}
I have the following class hierarchy:
public abstract class BaseClass : IBaseInterface
{
public int PropertyA{
get
{
return this.propertyA;
}
set
{
this.propertyA = value;
// ... some additional processing ...
}
}
}
DerivedClassB : BaseClass
{
// some other fields
}
public class ContainingClassC
{
public IBaseInterface BaseInterfaceObjectD
{
get;
set;
}
}
Now, in order to access PropertyA of a DerivedClassB-Object (inherited from BaseClass), I have to cast the object to BaseClassA's ancestor, like so:
// This ContainingClassC is returned from a static, enum-like class:
// containingObject.PropertyA is DerivedClassB by default.
ContainingClassC containingObject = new ContainingClassC();
((IBaseInterface)containingObject.BaseInterfaceObjectD).PropertyA = 42;
Is there a way I can restructure these classes to do away with the cast? This code is part of a library, and my colleague wants me to get rid of the cast.
The goal is to simply write containingObject.BaseInterfaceObjectD.PropertyA = 42.
First of all in the line ((IBaseInterface)containingObject.BaseInterfaceObjectD).PropertyA = 42; you are casting the member to the same type that it is declared in, so the casting doesn't actually do anything.
To be able to access the PropertyA in the derived class - since you are casting it to an interface - the property must be declared in the interface and then implemented in the BaseClass.
public interface IBaseInterface{
int PropertyA{get;set;}
}
public abstract class BaseClass : IBaseInterface{
public int PropertyA{
get{ return this.propertyA;}
set {this.propertyA = value;}
}
}
As long as the interface is implemented properly, ProprtyA should be available in the base class, the derived class or with either of them cast'ed to the interface type.
If it's just a problem of the property not showing up in IntelliSense, then it might be a problem with your settings. Check out Options->Text Editor->C# and make sure you have IntelliSense turned on and not set to hiding anythig.
public interface ITest {
void Somethink();
}
public class Test1 : ITest {
public void Somethink() { /* do stuff */ }
public int Test1Property { get; set; }
}
public class Test2 : ITest {
public void Somethink() { /* do stuff */ }
public float Test2Property { get; set; }
}
//Main class
public class MainClass
{
[TypeConverter(ExpandableObjectConverter)]
public ITest test { get; set; }
}
Ok, i have sth like this. Instance of MainClass is selected by PropertyGrid.
How to make a DropDownList of objects of classes which implement ITest (here Test1 and Test2)
That's not how it works. The test property getter will return an object of a concrete class that implements ITest. Whatever was assigned to it last, either null, an object of Test1 or an object of Test2. PropertyGrid uses Reflection to look at the object Type and its members. It will display either Test1Property or Test2Property. You cannot choose.
Not sure what you are trying to do, you probably want a UITypeEditor if you want to assign an object of a different type.
Ok, I used UITypeEditor (thx nobugz), and create combobox for possible values. The values i get from Type[] BehaviorManager.GetBehaviorsWhichImplement(Type type) - that return an array of types implementing given interface.
When user have select a new value, i get a new instance of selected Object BehaviorManager.GetBehavior(Type) which using a Activator.CreateInstance. And assign it to Property.
Of course, it isn't a dropdownlist, but it's pretty good too :-)
here is a article which i following - http://philwinkel.com/blog/?p=4
I know, my grammer is tragic, sorry, i'm still trying to do sth with this ;-)