NSubstitute Mocking new T property - c#

I try to create a mock for an existing interface. When I try to read the value, I get a null reference exception
public interface MyInterface<T> : MyInterface
{
new T Value { get; set; }
}
public interface MyInterface : MyReadonlyInterface
{
new object Value { get; set; }
}
public interface MyReadonlyInterface
{
object Value { get; }
}
...
var i = Substitute.For<MyInterface<bool>>();
variable.Value = false;
Just after inititialize I see the value as "false". Later in the test, the value will become NULL. The usualy used
variable.Value.Returns(false)
also shows NULL.
How do I have to use NSubstitute to get the required "false" without changing the interface?

Related

An issue with designing my interfaces in C# : Sample Project

I have a problem with designing my interfaces
I have these interfaces :
interface IField {
}
interface IScreenField : IField {
}
interface ITable {
CustomCollection<IField> CustomCollection { get; set; }
}
interface IScreen
{
AnotherCustomCollection<IScreenField> AnotherCustomCollection { get; set; }
}
IScreen interface should inherit from ITable but it shows an error that I have to implement a collection of IField but I already implement a collection of IScreenField
What is the soltuion for this ?
I uploaded a sample project to explain the issue more
You can check the error message in Screen class that says :
Screen does not implement interface member ITable.Fields. Screen.Fields cannot implement ITable.Fields becuase it does not have the matching return type of CusomCollection<IField>
Here is the sample :
Sample project
This description of this example helps you to solve the problem: If IExample2 inherits another Interface, when implementing IExample2 u need to implement
all the method(properties etc...) that has been declared in interface + the method of inhered interfaces from IExample2. Remember that when you implement an interface you have to implement all of members of that interface (you have to implement even the members of all interfaces that are in chain) and all the returns types has to be the same in interface and in class.
interface IExample
{
void Method1();
}
interface IExample2 : IExample
{
void Method2();
}
class Screen : IExample2
{
public void Method2()
{
}
public void Method1()
{
}
}
Chain Example
interface IExample
{
void Method1();
}
interface IExample2 : IExample
{
void Method2();
}
interface IExample3 : IExample2
{
void Method3();
}
This is the answer I posted on your previous post. Reposting it here as-is since your previous question was put on hold before I could
submit the answer.
It’s very difficult to identify the problem without looking at the full code but based on what you have said, I believe, you have implemented IScreenField explicitly and the compiler is not able to find any implementation of IField.
Checkout following for more info:
https://www.codeproject.com/Articles/1000374/Explicit-Interface-VS-Implicit-Interface-in-Csharp
Update: After looking at the code
First of all you need to understand difference between Implicit and Explicit implementations of an Interface:
Implicit: you access the interface properties and properties as if they were part of the class.
Explicit: you can only access properties and properties when treating the class as the implemented interface.
The problem with the Screen class is that it implements IScreen interface, which in-turn implements ITable interface. Both these interfaces have a property named Fields.
The problem surfaced due to this and you are required to
explicitly implement the Fields property in Screen class.
NOTE: It is irrelevant that you have different return types. Since you have implemented Fields property in both interfaces, it is assumed that you are expecting different values when the property is accessed from each of the interfaces.
public class Screen : IScreen
{
public string Name { get; set; }
AnotherCustomCollection<IBaseField> IScreen.Fields
{
get
{
return default(AnotherCustomCollection<IBaseField>);
}
}
CustomCollection<IField> ITable.Fields
{
get
{
return default(CustomCollection<IField>);
}
}
public string Title { get; set; }
public string Description { get; set; }
}
Now how to access them? To access Fields property of each of these Interfaces you need to access Screen object as those interfaces.
Ex:
var screen = new Screen();
var fields = screen.Fields; // Error
var fields = (screen as IScreen).Fields; // returns property value of IScreen Fields
var fields = (screen as ITable).Fields; // returns property value of ITable Fields
Here is the complete code: https://dotnetfiddle.net/5KS0Xd
Hope this was helpful. All the best and happy coding.
You could do something like this:
public class Screen : IScreen
{
public string Name { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public AnotherCustomCollection<IBaseField> Fields { get; set; }
CustomCollection<IField> ITable.Fields
{
get
{
throw new System.NotSupportedException();
}
}
}
And apparently the compiler likes that, and if you do something like this:
public static void Main(string[] args)
{
var collection = new List<IScreen>()
{
new Screen
{
Fields = new AnotherCustomCollection<ScreenInterface.IBaseField>
{
new TextField()
{
Name = "Hello"
}
}
}
};
var y = collection.First();
//Prints "Hello"
Console.WriteLine(string.Join(" ", y.Fields.Select(x => x.Name)));
Console.ReadLine();
}
But, if you are working with the upper interface (ITable)
public static void Main(string[] args)
{
var collection = new List<ITable>() //here
{
new Screen
{
Fields = new AnotherCustomCollection<ScreenInterface.IBaseField>
{
new TextField()
{
Name = "Hello"
}
}
}
};
var y = collection.First();
//Throws NotSupportedException
Console.WriteLine(string.Join(" ", y.Fields.Select(x => x.Name)));
Console.ReadLine();
}
My guess is that there isn't the concept of generic inheritance, and that may be proved if you switch the conditional generic parameter of AnotherCustomCollection from IBaseField to IField, and instead of throwing the exception, return the public Fields property on Screen.ITable.Fields. Compiler will automatically recognize the concrete property and everything will work.
So, for this to work, either define an implicit operator or a custom getter:
public class Screen : IScreen
{
public string Name { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public AnotherCustomCollection<IBaseField> Fields { get; set; }
CustomCollection<IField> ITable.Fields
{
get
{
var customCollection = new CustomCollection<IField>();
customCollection.AddRange(Fields);
return customCollection;
}
}
}

List of unknown generic types or invoke a generic subclass [duplicate]

Is it possible to add different type of generic objects to a list?. As below.
public class ValuePair<T>
{
public string Name { get; set;}
public T Value { get; set;
}
and let say I have all these objects...
ValuePair<string> data1 = new ValuePair<string>();
ValuePair<double> data2 = new ValuePair<double>();
ValuePair<int> data3 = new ValuePair<int>();
I would like to hold these objects in a generic list.such as
List<ValuePair> list = new List<ValuePair>();
list.Add(data1);
list.Add(data2);
list.Add(data3);
Is it possible?
In general, you'd have to either use a List<object> or create a non-generic base class, e.g.
public abstract class ValuePair
{
public string Name { get; set;}
public abstract object RawValue { get; }
}
public class ValuePair<T> : ValuePair
{
public T Value { get; set; }
public object RawValue { get { return Value; } }
}
Then you can have a List<ValuePair>.
Now, there is one exception to this: covariant/contravariant types in C# 4. For example, you can write:
var streamSequenceList = new List<IEnumerable<Stream>>();
IEnumerable<MemoryStream> memoryStreams = null; // For simplicity
IEnumerable<NetworkStream> networkStreams = null; // For simplicity
IEnumerable<Stream> streams = null; // For simplicity
streamSequenceList.Add(memoryStreams);
streamSequenceList.Add(networkStreams);
streamSequenceList.Add(streams);
This isn't applicable in your case because:
You're using a generic class, not an interface
You couldn't change it into a generic covariant interface because you've got T going "in" and "out" of the API
You're using value types as type arguments, and those don't work with generic variable (so an IEnumerable<int> isn't an IEnumerable<object>)
Not unless you have a non-generic base-type ValuePair with ValuePair<T> : ValuePair (it would work for an interface too), or use List<object>. Actually, though, this works reasonably:
public abstract class ValuePair
{
public string Name { get; set; }
public object Value
{
get { return GetValue(); }
set { SetValue(value); }
}
protected abstract object GetValue();
protected abstract void SetValue(object value);
}
public class ValuePair<T> : ValuePair
{
protected override object GetValue() { return Value; }
protected override void SetValue(object value) { Value = (T)value; }
public new T Value { get; set; }
}
No, it is not possible. You could create, in your case, a base class ValuePair from which ValuePair<T> derives. Depends on your purposes.
it's not possible as far as I know.
the line:
List<ValuePair> list = new List<ValuePair>();
you wrote in your sample is not providing a concrete type for T and this is the issue, once you pass it, you can only add object of that specific type.

Creating generic method to construct and return generic objects?

I want to create a method that will return a Response<> object and set the generic properties based on the type of the object passed in as a parameter. General code example below and additional considerations at the bottom of the post.
public class Response<T>
{
public string ResponseCode { get; get; }
public T Object { get; set;}
public List<T> Objects { get; set; }
public Response()
{
}
}
public class ChildrenResponses
{
public ChildrenResponses() // constructor
{
}
// some properties
}
public class AdultResponses
{
public AdultResponses() // constructor
{
}
// some properties
}
public Response<T> GetSpecificResponseType<T>(T genericType)
{
// ... some logic to instantiate a Response<> object using the parameter type passed into the method.
// ... some logic to set the generic properties of Response<> object based on the parameter type passed into the method.
// return object
}
I'm new to C# generics/reflection :)
Being as the Response/ChildrenResponse/AdultResponse classes existed in this code base before I began using it, I'd like to avoid changing those classes.
I've attempted multiple methods to accomplish this task, but none of them worked and providing them in this post would likely just add confusion. Instead, I provided a base method with the general idea I was working with.
An example of how I'd like to call the method:
Response<ChildrenResponses> result = GetSpecificResponseType<ChildrenResponses>("ChildrenResponses");
This method will then return the Response< ChildrenResponses > object with the Object property set to new ChildrenResponses() and Objects set to new List< ChildrenResponses >(). No properties within the ChildrenResponses need to be established - just the instantiating the object is enough.
All you need to do is restrict your generic method to require a type with a parameterless constructor. Then you should be able to do this:
public Response<T> GetSpecificResponseType<T>() where T : new()
{
return new Response<T>()
{
Object = new T(),
Objects = new List<T>()
}
}
Call like this:
Response<ChildrenResponses> result = GetSpecificResponseType<ChildrenResponses>();
I think what you are missing is an interface. It is kind of hard to tell exactly what you are trying to do, so here is the way I interpreted the question:
public class Response<T> where T: IRepsonses, new()
{
public string ResponseCode { get; set; }
public T Object { get; set; }
public List<T> Objects { get; set; }
public Response()
{
}
}
public interface IRepsonses
{
}
public class ChildrenResponses : IRepsonses
{
public ChildrenResponses() // constructor
{
}
public string ChildSays { get; set; }
// some properties
}
public class AdultResponses : IRepsonses
{
public AdultResponses() // constructor
{
}
public string AdultSays { get; set; }
// some properties
}
class Program
{
public static Response<T> GetSpecificResponseType<T>() where T: IRepsonses, new()
{
// ... some logic to instantiate a Response<> object using the parameter type passed into the method.
// ... some logic to set the generic properties of Response<> object based on the parameter type passed into the method.
// return object
T obj = new T();
return new Response<T>()
{
Object=obj,
Objects=new List<T>()
};
}
static void Main(string[] args)
{
var resp = GetSpecificResponseType<AdultResponses>();
var adult = resp.Object.AdultSays;
}
}

Adding different type of generic objects into generic list

Is it possible to add different type of generic objects to a list?. As below.
public class ValuePair<T>
{
public string Name { get; set;}
public T Value { get; set;
}
and let say I have all these objects...
ValuePair<string> data1 = new ValuePair<string>();
ValuePair<double> data2 = new ValuePair<double>();
ValuePair<int> data3 = new ValuePair<int>();
I would like to hold these objects in a generic list.such as
List<ValuePair> list = new List<ValuePair>();
list.Add(data1);
list.Add(data2);
list.Add(data3);
Is it possible?
In general, you'd have to either use a List<object> or create a non-generic base class, e.g.
public abstract class ValuePair
{
public string Name { get; set;}
public abstract object RawValue { get; }
}
public class ValuePair<T> : ValuePair
{
public T Value { get; set; }
public object RawValue { get { return Value; } }
}
Then you can have a List<ValuePair>.
Now, there is one exception to this: covariant/contravariant types in C# 4. For example, you can write:
var streamSequenceList = new List<IEnumerable<Stream>>();
IEnumerable<MemoryStream> memoryStreams = null; // For simplicity
IEnumerable<NetworkStream> networkStreams = null; // For simplicity
IEnumerable<Stream> streams = null; // For simplicity
streamSequenceList.Add(memoryStreams);
streamSequenceList.Add(networkStreams);
streamSequenceList.Add(streams);
This isn't applicable in your case because:
You're using a generic class, not an interface
You couldn't change it into a generic covariant interface because you've got T going "in" and "out" of the API
You're using value types as type arguments, and those don't work with generic variable (so an IEnumerable<int> isn't an IEnumerable<object>)
Not unless you have a non-generic base-type ValuePair with ValuePair<T> : ValuePair (it would work for an interface too), or use List<object>. Actually, though, this works reasonably:
public abstract class ValuePair
{
public string Name { get; set; }
public object Value
{
get { return GetValue(); }
set { SetValue(value); }
}
protected abstract object GetValue();
protected abstract void SetValue(object value);
}
public class ValuePair<T> : ValuePair
{
protected override object GetValue() { return Value; }
protected override void SetValue(object value) { Value = (T)value; }
public new T Value { get; set; }
}
No, it is not possible. You could create, in your case, a base class ValuePair from which ValuePair<T> derives. Depends on your purposes.
it's not possible as far as I know.
the line:
List<ValuePair> list = new List<ValuePair>();
you wrote in your sample is not providing a concrete type for T and this is the issue, once you pass it, you can only add object of that specific type.

Using Generics in Interfaces

How do I allow my CookieData to be generic in the following code? I get an compile-time error on the declaration of ICookieService2.
public struct CookieData<T>
{
T Value { get; set; }
DateTime Expires { get; set; }
}
public interface ICookieService2: IDictionary<string, CookieData<T>>
{
// ...
}
My error is:
The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)
I am wanting ICookieService2 to have generic data inserted into it. Thanks!
Edit Won't that lock me into a single T for the construction of any ICookieService2?
Edit 2 What I am trying to do is the following:
CookieData<int> intCookie = { Value = 27, Expires = DateTime.Now };
CookieData<string> stringCookie = { Value = "Bob", Expires = DateTime.Now };
CookieService2 cs = new CookieService2();
cs.Add(intCookie);
cs.Add(stringCookie);
It looks like you have 3 options here
Make ICookieService2 generic
public interface ICookieService2<T> : IDictionary<string, CookieData<T> {
...
}
Create a non-generic base class for CookieData and use that in the interface
public interface ICookieData {}
public class CookieData<T>: ICookieData{}
public interface ICookieService2 : IDictionary<string, ICookieData> {}
Pick a concrete implementation
public interface ICookieService : IDictionary<string, CookieData<int>> {}
You must make ICookieService2 generic as well:
public interface ICookieService2<T>: IDictionary<string, CookieData<T>>
{
// ...
}
OK, here's what you want:
public interface ICookieDataBase
{
DateTime Expires { get; set; }
}
public struct CookieData<T> : ICookieDataBase
{
public T Value { get; set; }
public DateTime Expires { get; set; }
}
public class ICookieService : IDictionary<string, ICookieDataBase>
{
// ...
}
public void DoWork()
{
var intCookie =
new CookieData<int> { Value = 27, Expires = DateTime.Now };
var stringCookie =
new CookieData<string> { Value = "Bob", Expires = DateTime.Now };
ICookieService cs = GetICookieService();
cs.Add(intCookie);
cs.Add(stringCookie);
}
You need a non-generic interface to do this:
public interface ICookieData
{
// you need this to get the value without knowing it's type
object UntypedValue { get; }
// whatever you need additionally ...
Type DataType { get; }
DateTime Expires { get; set; }
}
public struct CookieData<T> : ICookieData
{
// ICookieData implementation
public object UntypedValue { get { return Value; } }
public Type DataType { get { return typeof(T); } }
public DateTime Expires { get; set; }
// generic implementation
T Value { get; set; }
}
public interface ICookieService2: IDictionary<string, ICookieData>
{
// ...
}
CookieData<int> intCookie = { Value = 27, Expires = DateTime.Now };
CookieData<string> stringCookie = { Value = "Bob", Expires = DateTime.Now };
CookieService2 cs = new CookieService2();
cs.Add(intCookie);
cs.Add(stringCookie);
I think what you want is:
public interface ICookieService2<T>: IDictionary<string, CookieData<T>>
{
// ...
}
currently ICookieService2 is not generic, so T is not defined.
This allows you to create classes the implement ICookieService2<string> or ICookieService2<int>, etc.
EDIT:
Responding to your latest request, I think it really depends on exactly what it is you need. However, something like this may work for you.
public interface ICookieData
{
object Value {get;} // if you need to be able to set from CookieService, life gets harder, but still doable.
DateTime Expires {get;}
}
public struct CookieDate<T> : ICookieData
{
T Value {get;set;}
DateTime Expires {get;set;}
object ICookieData.Value
{
get
{
return Value;
}
}
}
Then CookieService can be or have a List and you would be able to add both CookieData and CookieData. If you need to be to write (set) from CookieService, its a little more complicated, and possibly better to not use generics. But if you just need to be able to retrieve the CookieData, then this might work for you.
not sure about C#, but the Java way would be to also declare your ICookieService2 to have the <T> parameter, or to specify the <T> to something concrete in CookieData.
If I understand your question correctly you are wanting to treat the generic types like they are the same, but in current .NET implementation you can't do this.
CookieData<string> can't be passed as a CookieData<int> they are actually different types, the generic types are not related and can't be cast or passed like they are the same. Creating ICookieService2 as an open generic (meaning ICookieService2<T>) doesn't solve the problem because then you would have a different ICookieService2 type for every different type and all of them would be in a different dictionary.
You can create a ICookieData interface and implement it in CookieData<T> and use ICookieData to store the items in the dictionary (as Stefan has already suggested).
You can do what you want in C# 4.0 (with a few restrictions). There is an article about it here until then, you have to pass it as a non-generic type that is common to them such as an interface or just have the value parameter be an object on the dictionary because you are going to have to case it to use it anyway if you are using primitives as the type arguments.
You could try
public struct CookieData<T>
where T : Object
{
T Value { get; set; }
DateTime Expires { get; set; }
}
That way all instances of T would be forced to have a base type of Object. (pretty much everything in C# (e.g. int == System.Integer etc.).

Categories

Resources