I have been trying to learn dependency injection but I have 2 errors when I run my code:
DependencyInjection.Message.Sms() must declare a body because it is not marked abstract, extern, or partial.
Cannot implicitly convert type DependencyInjection.IInterface to DependencyInjection.MyClass. An explicit conversion exists (are you missing a cast?)
Is the code below a good design for DI?
namespace DependencyInjection
{
public interface IInterface
{
}
public abstract class Message
{
public virtual void Sms();
}
public class MyClass : Message, IInterface
{
public override void Sms()
{
Console.WriteLine("Sms gönder.");
}
}
public class ClassManager
{
private IInterface _myinterface;
public MyClass Xyz
{
get { return _myinterface; }
set { _myinterface = value; }
}
public ClassManager(IInterface myinterface)
{
_myinterface = myinterface;
}
}
}
1) DependencyInjection.Message.Sms()' must declare a body because it is not marked abstract, extern, or partial
Add abstract keyword (and remove virtual) to method declaration:
public abstract void Sms();
2) Cannot implicitly convert type 'DependencyInjection.IInterface' to 'DependencyInjection.MyClass'. An explicit conversion exists (are you missing a cast?)
private IInterface _myinterface;
public MyClass Xyz
{
get { return _myinterface; }
set { _myinterface = value; }
}
Xyz has return-type of type MyClass but in get you are returning _myinterface which is of type IInterface.
Change to following:
public IInterface Xyz
{
get { return _myinterface; }
set { _myinterface = value; }
}
Change this
public abstract class Message
{
public virtual void Sms();
}
to this
public abstract class Message
{
public abstract void Sms();
}
You either give the virtual method a body, like so
public virtual void Sms() { }
or you mark it as abstract
public abstract void Sms();
EDIT:
Forgot about the second error. Change this
public MyClass Xyz
{
get { return _myinterface; }
set { _myinterface = value; }
}
to this
public IInterface Xyz
{
get { return _myinterface; }
set { _myinterface = value; }
}
You're declaring a virtual method with no body. Virtual methods must declare a body that will act as the default implementation of the method. You can either declare your method as abstract, which means that the derived classes have to provide their own implementation:
public abstract void Sms();
or you can keep the method virtual and provide a default implementation in the base class:
public virtual void Sms()
{
// Default or no implementation goes here.
}
In the following code you're trying to cast IInterface to MyClass, which is probably not what you want.
public MyClass Xyz
{
get { return _myinterface; }
set { _myinterface = value; }
}
you're probably looking to return IInterface instead:
public IInterface Xyz
{
get { return _myinterface; }
set { _myinterface = value; }
}
Related
How can you cast an interface with a generic type to a common interface?
Lets say we have the following interfaces/objects:
public interface IAction : IAction<object> { }
public interface IAction<T>
{
T PerformAction();
}
public class SomeAction : IAction<string>
{
public string PerformAction()
{
return "some action result value";
}
}
public class OtherAction : IAction<int>
{
public int PerformAction()
{
return 100;
}
}
Then if we try to code it in a console application:
List<IAction> actions = new List<IAction>();
actions.Add(new SomeAction());
actions.Add(new OtherAction());
actions.ForEach(e => Console.WriteLine(e.PerformAction()));
How can we work around the error "cannot convert from 'SomeAction' to 'IAction'"?
Your inheritance hierarchy does not make sense, you should have IAction<T> extend IAction and not the other way around.
You also need to add any common methods you want to call to IAction and, if the methods have the same name and parameters, implement them using an explicit interface implementation. It is on the common interface implementation you will be calling the method.
public interface IAction
{
object PerformAction();
}
public interface IAction<T> : IAction
{
new T PerformAction();
}
public class SomeAction : IAction<string>
{
object IAction.PerformAction()
{
return PerformAction();
}
public string PerformAction()
{
return "some action result value";
}
}
public class OtherAction : IAction<int>
{
object IAction.PerformAction()
{
return PerformAction();
}
public int PerformAction()
{
return 100;
}
}
Calling code
List<IAction> actions = new List<IAction>();
actions.Add(new SomeAction());
actions.Add(new OtherAction());
actions.ForEach(e => Console.WriteLine(e.PerformAction()));
I really need to have something like this:
interface IReadableVar
{
object Value { get; }
}
interface IWritableVar
{
object Value { set; }
}
interface IReadableWritableVar : IReadableVar, IWritableVar
{
}
However when I try to use IReadableWritableVar.Value I get compile errors unless I explicitly cast to base interface, like here:
static void Main()
{
IReadableWritableVar var = null;
var t = var.Value; // <-- CS0229: Ambiguity between 'IReadableVar.Value' and 'IWritableVar.Value'
var.Value = null; // <-- CS0229: Ambiguity between 'IReadableVar.Value' and 'IWritableVar.Value'
var v = ((IReadableVar)var).Value; // compiles fine
((IWritableVar)var).Value = null; // compiles fine
}
Why do I get these errors although everything should be clear to the compiler? Is there any way to fix this problem other than casting (hundreds of places in the application)?
Update: it was suggested this is a dupe of Implementing 2 Interfaces with 'Same Name' Properties but this is slightly different as in the other case there's no inheritance in interfaces. Anyway, the problem is solved now - see accepted answer.
A possible workaround can be modify your interface IReadableWritableVar like this:
interface IReadableWritableVar : IReadableVar, IWritableVar
{
new object Value { get; set; }
}
But keep in my that a valid implementation should be:
class ReadableWritableVar : IReadableWritableVar
{
public object Value
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
object IWritableVar.Value
{
set { throw new NotImplementedException(); }
}
object IReadableVar.Value
{
get { throw new NotImplementedException(); }
}
}
A more concrete example:
class ReadableWritableVar : IReadableWritableVar
{
public object Value
{
get { return ((IReadableVar)this).Value; }
set { ((IWritableVar)this).Value = value; }
}
object _val;
object IWritableVar.Value { set { _val = value; } }
object IReadableVar.Value => _val;
}
Or even better:
class ReadableWritableVar : IReadableWritableVar
{
public object Value { get; set; }
object IWritableVar.Value { set { Value = value; } }
object IReadableVar.Value => Value;
}
Interesting question. I think extension methods will help in this case.
public static class Extension
{
public static object GetValue(this IReadableVar v)
{
return v.Value;
}
public static void SetValue(this IWritableVar v, object value)
{
v.Value = value;
}
}
You need to change the code to use it:
IReadableWritableVar variable = null;
var t = variable.GetValue();
variable.SetValue(null);
The extension method does the cast for you.
Well, effectively Getter and Setter are just two methods. When we use IReadableWritableVar interface there are two methods with identical name inherited from base interfaces and compiler doesn't know which of these two should it use hence the ambiguity.
When we cast that to one of these interfaces the other member's gone and there's no error.
If we implement those member there will be no error as compiler will use that implementation:
class ReadableWritableVar : IReadableWritableVar
{
public object Value { get; set; }
}
var #var = new ReadableWritableVar();
var t = #var.Value;
Also you can use an explicit interface members implementation from #Alessandro D'Andria's answer if it is required that you use interface and not class.
using abstract class istead of interface will resolve your problem.
public abstract class ReadableWritableVar : IReadableVar, IWritableVar
{
public object Value { get; set; }
}
One possible alternative is to use explicit (java style) get and set methods instead of a property:
interface IReadableVar
{
object GetValue();
}
interface IWritableVar
{
void SetValue(object value);
}
interface IReadableWritableVar : IReadableVar, IWritableVar
{
}
The usage then becomes:
static void Main(string[] args)
{
IReadableWritableVar aVar = null;
var t = aVar.GetValue();
aVar.SetValue(null);
}
I'm sorry if this is poorly worded or if this has been asked before but I couldn't seem to find anything related to this and I'm quite tired.
Alright, so what I'm trying to do is get the value of of my trait in a subclass for situations where I need to reference an instance of a subclass but I don't have the information about what trait it will be using. This is easier for me to explain in code so here's what I'm trying to do.
public class TraitUser<T>
{
public void DoThingWithT(T thing)
{
thing.ToString();
}
}
public class TraitInspector
{
public void DoThing()
{
// This is where I run into my issue,
// I need to be able to get the trait that
// an instance of the TraitUser class is using to continue.
TraitUser<> tUser = GetRandomTraitUser()/*Imagine this returns an instance of TraitUser with a random trait, this is where my issue comes in.*/;
}
}
If I understand youright, you need get information about generic type T in TraitUser instance in TrairInspector.
public interface IGetTraitInfo
{
Type GetTraitObjectType();
object GetTraitObject();
}
public class TraitUser<T> : IGetTraitInfo
{
private T _thing;
public void DoThingWithT(T thing)
{
_thing = thing;
}
public Type GetTraintObjectType()
{
return typeof(T);
}
public Type GetTraitObject()
{
return _thing;
}
}
public class TrairInspector
{
public void InspectTraitUser(IGetTraitInfo traitUser)
{
Type traitType = traitUser.GetTraintObjectType();
object data = traitUser.GetTraitObject();
}
}
I didn't understand completely but this might help you.
public interface ITrait
{
string DoSomething();
}
public class Trait<T> where T : ITrait, new()
{
public string DoSomething()
{
ITrait trait = new T();
return trait.DoSomething();
}
}
public class TraitUser : ITrait
{
public string DoThing()
{
return "return something";
}
}
public class TrairInspector
{
public void DoThing()
{
Trait<TraitUser> traitUser = new Trait<TraitUser>();
traitUser.DoSomething();
}
}
EDIT: This question would be invalid in .NET 4 since it actually works as desired.
I have a Data class that must implement an interface like this:
public interface IData
{
IEnumberable<IOther> OtherList { get; }
IOther AddOther();
void RemoveOtherData(IOther data);
}
But I am stuck with declaring the actual member in Data
public class Data : IData
{
// desired, always return the same reference
public IEnumberable<IOther> OtherList { get { return _mOtherList } }
// Non persistent reference not desirable.
public IEnumerable<IOther> OtherList { get { return _mOtherList.Select(x => x as IOther); } }
List<IOther> _mOtherList = new List<Other>(); // error, type mismatch
List<Other> _mOtherList = new List<Other>(); // error, property return type mismatch
IEnumerable<IOther> _mOtherList = new List<Other>(); // ok, but cannot use List methods without casting.
}
What would be the best solution in this case?
public class Data : IData
{
public IEnumerable<IOther> OtherList { get; private set; }
List<Other> _mOtherList = new List<Other>();
public Data()
{
OtherList=mOtherList.Cast<IOther>();
}
}
On .net 4 IEnumerable<out T> is co-variant. i.e. a class that implements IEnumerable<Other> automatically implements IEnumerable<IOther> too. So could also simply write:
public class Data : IData
{
public IEnumerable<IOther> OtherList { get{return mOtherList;} }
List<Other> _mOtherList = new List<Other>();
}
But I'd avoid that, since it breaks encapsulation and allows outsiders to modify your list.
((List<Other>)MyData.OtherList).Add(...);
Other class must implement IOther interface and you don't need to cast.
When you declare _mOtherList, it's IEnumerable, so you can't use list methods. Declare it as a list.
public class Data : IData
{
List<IOther> _mOtherList = new List<Other>();
public IEnumberable<IOther> OtherList { get { return _mOtherList } }
IOther AddOther()
{
return null;
}
void RemoveOtherData(IOther data){}
}
Your Other class:
class Other : IOther
{
//some members
}
As IEnumerable is covariant this is fine:
public interface IInterface{}
public class ClassA : IInterface{}
public class ClassB
{
private readonly List<ClassA> _classAs;
public IEnumerable<IInterface> Data{ get { return _classAs; } }
}
I need to have a wrapper class that exposes some properties of my entity class called ProfileEntity.
I tried doing it by deriving from this entity and then creating properties that return specific entity properties, but it says I cannot cast from ProfileEntity to ProfileEntityWrapper.
When I try to put the return values of a method that returns a 'ProfileEntity' into the wrapper I get the above error.
How do I create such a wrapper class that is castable?
Example
class ProfileEntityWrapper : ProfileEntity
{
public string Name
{
get
{
return this.ProfileEntityName;
}
}
}
public class Someclass
{
public ProfileEntity SomeMethod()
{
return ProfileEntity; // example of method returning this object
}
}
public class SomeOtherlClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
ProfileEntityWrapper ew = (ProfileEntityWrapper)sc.SomeMethod(); // Cannot do this cast!!!
}
}
You cannot cast an object of ProfileEntity to ProfileEntityWrapper.
var entity = new ProfileEntity(); // this object is only of type ProfileEntity
var wrapper = new ProfileEntityWrapper(); // this object can be used as both ProfileEntityWrapper and ProfileEntity
You probably want to return a ProfileEntityWrapper in SomeMethod():
public class Someclass
{
public ProfileEntity SomeMethod()
{
return new ProfileEntityWrapper(); // it's legal to return a ProfileEntity
}
}
No, that is not possible.
To accomplish this problem you can maybe try this one:
public class ProfileEntity
{
public string ProfileEntityName { get; set; }
}
public class ProfileEntityWrapper
{
public ProfileEntityWrapper(ProfileEntity entity)
{
Entity = entity;
}
public ProfileEntity Entity { get; private set; }
public string Name
{
get
{
return Entity.ProfileEntityName;
}
}
}
public class SomeClass
{
public ProfileEntity SomeMethod()
{
// example of method returning this object
ProfileEntity temp = new ProfileEntity();
return temp;
}
}
public class SomeOtherClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
//Create a new Wrapper for an existing Entity
ProfileEntityWrapper ew = new ProfileEntityWrapper(sc.SomeMethod());
}
}
If you are allowed to edit the ProfileEntity class, or if the ProfileEntity class is a generated partial class, you could add an interface instead of using a wrapper. You wouldn't need to do any casting with an interface either. Example:
public interface IProfile
{
string Name { get; }
}
public partial class ProfileEntity : IProfile
{
public string Name
{
get
{
return this.ProfileEntityName;
}
}
}
public class SomeClass
{
public ProfileEntity SomeMethod()
{
return ProfileEntity;
}
}
public class SomeOtherClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
IProfile ew = sc.SomeMethod();
}
}
The IProfile instance will only provide access to the Name property.
This's no correct code from polymorphism aspect.
If we will take the famous polymorphism example when there're base Shape class and Circle, Polygon and Rectangle classes that extend the Shape class, your code will try to cast some shape into circle and as you understand this's invalid casting operation.
So to make this code work you must be sure that SomeClass.SomeMethod() will return instance of ProfileEntityWrapper or perform type check before the casting, like this:
ProfileEntity temp = sc.SomeMethod();
if(temp is ProfileEntityWrapper)
ProfileEntityWrapper ew = (ProfileEntityWrapper) temp;