I am trying to change the property type in interface implementation class using explicit interface implementation.
interface ISample
{
object Value { get; set; }
}
class SampleA : ISample
{
SomeClass1 Value { get; set; }
object ISample.Value
{
get { return this.Value; }
set { this.Value = (SomeClass1)value; }
}
}
class SampleB : ISample
{
SomeClass2 Value { get; set; }
object ISample.Value
{
get { return this.Value; }
set { this.Value = (SomeClass2)value; }
}
}
class SomeClass1
{
string s1;
string s2;
}
But when I need to pass in interface obj in a function, I cant access the objects of SomeClass1 or SomeClass2.
For eg:
public void MethodA(ISample sample)
{
string str = sample.Value.s1;//doesnt work.How can I access s1 using ISample??
}
I don't know if this is understandable, but I cant seem to get an easier way to explain this. Is there a way to access the properties of SomeClass1 using interface ISample?
Thanks
That is because you've received the object as the interface, so it doesn't know about the class's new property type. You would need to:
public void MethodA(ISample sample)
{
if (sample is SampleA)
{
string str = ((SampleA)sample).Value.s1;
}
}
A better solution might be to use the visitor pattern - which would have implementations for handling the different ISample's.
Related
The main purpose is to show intellisense when setting the property. It would be great if I could do it via an attribute like the image below.
The property should remain a string(not enum or struct) so that Mongo's BsonSerializer can serialize it properly. Here is an example of what it might look like:
To help other developers on the team know possible (but not exlusive) values they can use for the Type field Code Completion should display values that can be used as shown below:
(Edited) I was able to solve this by creating my own type
public class SkinType:StringType<SkinType>
{
public SkinType(string value)
{
Value = value;
}
public SkinType()
{
}
public static implicit operator string(SkinType d)
{
return d.Value;
}
public static implicit operator SkinType(string d)
{
return new SkinType(d);
}
public const string StringValue = nameof(StringValue);
public const string Color = nameof(Color);
}
Now I get intellisense for my Type property and Mongo knows how to serialize it.
Here is how I use it:
public class Skin : ServiceMongoIdentity
{
//removed some properties for brevity.
[BsonIgnoreIfDefault]
[BsonDefaultValue(SkinType.StringValue)]
public SkinType Type { get; set; } = SkinType.StringValue;
}
Here is how the StringType base class is defined. I had to make Value public because Generics cannot have constructors with parameters
public abstract class StringType<T> where T :StringType<T>,new()
{
[ReadOnly(true)]
public string Value;
public T FromString(string d)
{
return new T
{
Value = d
};
}
public override bool Equals(object obj)
{
return obj?.ToString() == Value;
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
return Value;
}
}
I have this weird behavior of AutoMapper. If I have a class that implements two interfaces were both of them are registered in CreateMap only one of them gets mapped and I do not understand why. It looks as if AutoMapper mapped only interface that is mentioned at first place in interfaces list.
Any thoughts? Please, checkout the following fiddler to see what the problem is.
Code from fiddler
A DTO to which I'd like to map:
class Dto {
public string StringValue {get;set;}
public int Value {get;set;}
}
Interfaces - sources from which I'd like to map:
interface ISourceA {
int Value {get;}
}
interface ISourceB {
string StringValue {get;}
}
...and two implementations for those. One that works, the other not really :/
class MultiSource: ISourceA, ISourceB {
private readonly string _s;
private readonly int _v;
public MultiSource(int v, string s) {
_v = v;
_s = s;
}
int ISourceA.Value { get { return _v; }}
string ISourceB.StringValue { get { return _s; }}
}
class StringSource: ISourceB {
public StringSource(string value) {
StringValue = value;
}
public string StringValue {get; private set;}
}
Here's how I use it:
public class Program
{
public static void Main()
{
Mapper.CreateMap<ISourceA, Dto>();
Mapper.CreateMap<ISourceB, Dto>();
var ms = new MultiSource(234, "woefjweofij");
var ss = new StringSource("iuahergiuw");
// This one is fine
Console.WriteLine(JsonConvert.SerializeObject(Mapper.Map<Dto>((ISourceA)ms)));
// This one is the same as that above. This is not what I intended to have in return :/
Console.WriteLine(JsonConvert.SerializeObject(Mapper.Map<Dto>((ISourceB)ms)));
// This works as expected
Console.WriteLine(JsonConvert.SerializeObject(Mapper.Map<Dto>(ss)));
}
}
I need a little pattern direction here. New to C#.
I'm working with a third-party development kit that wraps a web service. There are two specific classes I deal with that, while relatively similar, are in two different namespaces in the dev kit and there's no common base class. I'd like to program against a common interface for them both however. I haphazardly threw together an implementation that essentially wraps the wrapper, but I feel rather certain it's not the most efficient method due to the incessant type casting.
I've been digging through articles on adapters, interfaces, extension methods, etc., but I'm running low on time, so if I could get a push in one direction that'd be greatly appreciated.
using ThirdParty.TypeA.Employee;
using ThirdParty.TypeB.Employee;
public class Employee
{
private object genericEmployee;
private EmployeeType empType;
public enum EmployeeType
{
TypeA = 0;
TypeB = 1;
}
public Employee(Object employee, EmployeeType type)
{
genericEmployee = employee;
empType = type;
}
public String Name
{
if (empType == EmployeeType.TypeA)
return (ThirdParty.TypeA.Employee)genericEmployee.Name;
else
return (ThirdParty.TypeB.Employee)genericEmployee.Name;
}
public String Age
{
if (empType == EmployeeType.TypeA)
return (ThirdParty.TypeA.Employee)genericEmployee.Age;
else
return (ThirdParty.TypeB.Employee)genericEmployee.Age;
}
}
Rev 2:
class EmployeeTypeAAdapter : TypeA, IEmployeeAdapter
{
TypeA _employee;
public EmployeeTypeAAdapter(TypeA employee)
{
_employee = employee
}
public String Name
{
get { return _employee.Name; }
set { _employee.Name = value; }
}
public String Balance
{
get
{
if (_employee.Balance != null)
{
decimal c = _employee.Balance.Amount;
return String.Format("{0:C}", c);
}
else
{
return "";
}
}
}
//...
}
class EmployeeTypeBAdapter : TypeB, IEmployeeAdapter
{
TypeB _employee;
public EmployeeTypeAAdapter(TypeB employee)
{
_employee = employee
}
public String Name
{
get { return _employee.Name; }
set { _employee.Name = value; }
}
public String Balance
{
get
{
if (_employee.Balance != null)
{
decimal c = _employee.Balance.Amount;
return String.Format("{0:C}", c);
}
else
{
return "";
}
}
}
//....
}
Try this approach:
public interface IEmployeeAdapter
{
string Age { get; set; }
string Name { get; set; }
}
class EmployeeTypeAAdapter : TypeA, IEmployeeAdapter
{
public EmployeeTypeAAdapter(TypeA employee) { }
}
class EmployeeTypeBAdapter : TypeB, IEmployeeAdapter
{
public EmployeeTypeBAdapter(TypeB employee) { }
}
public static class EmployeeAdapterFactory
{
public static IEmployeeAdapter CreateAdapter(object employee, EmployeeType type)
{
switch (type)
{
case EmployeeType.TypeA: return new EmployeeTypeAAdapter((TypeA)employee);
case EmployeeType.TypeB: return new EmployeeTypeBAdapter((TypeB)employee);
}
}
// or without enum
public static IEmployeeAdapter CreateAdapter(object employee)
{
if (employee is TypeA) return new EmployeeTypeAAdapter((TypeA)employee);
if (employee is TypeB) return new EmployeeTypeABdapter((TypeB)employee);
}
// or better introduce sort of type map
}
Another proper name is EmployeeProxy, as you prefer.
What you're trying to do is known as Duck typing. You can do this using adapter classes and a shared interface, but creating these adapters manually requires a lot of repetitive glue code. One way you can get around writing the glue code is to construct the adapter type dynamically. You can do this yourself via IL Emit (a worthwhile exercise if you've never had a chance to play with it before, though there can be quite a few boundary cases to consider.) If you're just interested in getting it working, however, you might check out this project as a place to start. The C# 'dynamic' type could also be used (and winds up doing some of the same code generation behind the scenes), but it doesn't give you a reference you can pass around to non-dynamic code as if it were an interface type.
I got an abstract base class
public class Base
{
public abstract String Info { get; }
}
and some children.
public class A : Base
{
public override String Info { get { return "A does ..."; } }
}
public class B : Base
{
public override String Info { get { return "B does ..."; } }
}
This is mere a constant but I want to make sure using Base that all classes implement it.
Now I sometimes do not have an object instance but want to access A.Info - this is not possible due it is a instance property.
Is there another way than implementing the same property on instance AND on static level? That would be feel like a duplicate violating DRY programming style.
NEW EDIT: I now see this two solutions:
public class Base
{
public abstract String ClassInfo { get; }
}
public class A : Base
{
public override String ClassInfo { get { return Info; } }
public static String Info { get { return "A does ..."; } }
}
public class B : Base
{
public override String ClassInfo { get { return Info; } }
public static String Info { get { return "In B we do ..."; } }
}
With this I can do with any object of type Base something like object.ClassInfo but also use the value in my factory hardcoded like if(A.Info) return new A(). But I have to implement two properties for the same information in every class.
On the other hand:
public class Base
{
public abstract String ClassInfo { get; }
public static String GetClassInfo<T>() where T : BaseControl, new()
{
T obj = new T();
return obj.ClassInfo;
}
}
public class A : Base
{
public override String ClassInfo { get { return "text A"; } }
}
public class B : Base
{
public override String ClassInfo { get { return "text B"; } }
}
Due to the abstract Base it is made sure that ClassInfo is always implemented. Calls with obj.ClassInfo and Base.GetClassInfo<A>() are okay. But with this every child of Base must have a default constructor without arguments and we loose performance with the unneccessary created instance.
Is there any other idea? Which one would you prefer and why?
If you need specific return results of your static properties, you're better of either
a) Instance properties
2) Attributes
In the example you've already given, you've got an instance of Base, which means you can just make the instance property virtual:
public class Base
{
public virtual string Info { get { return "From Base"; } }
}
public class A : Base
{
public override string Info { get { return "From A"; } }
}
If you wanted to go the attribute route, you define it as such:
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class InfoAttribute : Attribute
{
public InfoAttribute(string info) { this.Info = info; }
public string Info { get; private set; }
}
[InfoAttribute(Info = "From Base")]
public class Base
{
public string GetInfo()
{
var attr = GetType()
.GetCustomAttributes(typeof(InfoAttribute), true)
.FirstOrDefault();
return (attr == null) ? null : attr.Info;
}
}
[InfoAttribute(Info = "From A")]
public class A : Base { }
If you wanted to call it as a static function call, you could make this change:
public static string GetInfo(Base instance)
{
var attr = instance.GetType()
.GetCustomAttributes(typeof(InfoAttribute), true)
.FirstOrDefault();
return (attr == null) ? null : attr.Info;
}
And then call it as: Base.GetInfo(instance);. All in all, not very elegant!
This is not possible.
static members cannot be virtual or abstract.
You should make an abstract instance property.
Statics can't be overridden. If you truly want to do something like that, you'd want an instance property that is virtual in the base that gets overridden in the subclasses.
Does it compiled? I don't think so. Static cannot be marked as override, virtual or abstract.
I need a base class with a property where I can derive classes with the same property but different (compatible) types. The base Class can be abstract.
public class Base
{
public virtual object prop { get; set; }
}
public class StrBase : Base
{
public override string prop { get; set; } // compiler error
}
public class UseIt
{
public void use()
{
List<Base> l = new List<Base>();
//...
}
}
I tried it with Generics but that gives me a problem when using the class, because I want to store differently typed base classes in the List.
public class BaseG<T>
{
public T prop { get; set; }
}
public class UseIt
{
public void use()
{
List<BaseG> l = new List<BaseG>(); // requires type argument
//...
}
}
Here's an alternative approach to proposed solution:
public abstract class Base
{
public abstract void Use();
public abstract object GetProp();
}
public abstract class GenericBase<T> : Base
{
public T Prop { get; set; }
public override object GetProp()
{
return Prop;
}
}
public class StrBase : GenericBase<string>
{
public override void Use()
{
Console.WriteLine("Using string: {0}", Prop);
}
}
public class IntBase : GenericBase<int>
{
public override void Use()
{
Console.WriteLine("Using int: {0}", Prop);
}
}
Basically I've added a generic class in the middle that stores your properly-typed property. this will work assuming that you never need to access Prop from the code that iterates the members of the List<Base>. (You could always add an abstract method to Base called GetProp that casts the generic to an object if that's required.)
Sample usage:
class Program
{
static void Main(string[] args)
{
List<Base> l = new List<Base>();
l.Add(new StrBase {Prop = "foo"});
l.Add(new IntBase {Prop = 42});
Console.WriteLine("Using each item");
foreach (var o in l)
{
o.Use();
}
Console.WriteLine("Done");
Console.ReadKey();
}
}
Edit: Added the GetProp() method to illustrate how the property can be directly accessed from the base class.
You can't override the type of a property. Take a look at the following code:
StrBase s = new StrBase();
Base b = s;
This is completely valid code. But what happens when you try to do this?
b.prop = 5;
The integer can be converted to object, because everything is derived from object. But since b is actually a StrBase instance, it would have to convert the integer to a string somehow, which it can't. So that is why you aren't allowed to override the type.
The same principle applies to generics:
List<BaseG<object>> l = new List<BaseG<object>>();
BaseG<string> s = new BaseG<string>();
// The compiler will not allow this.
l.add(s);
// Here's the same problem, convert integer to string?
BaseG<object> o = l[0];
o.prop = 5;
This is because generic types in C# 2.0 are invariant. C# 4.0 does allow this type of conversions, called covariance and contravariance.
Solutions
An option is to cast the object back to string when you need it. You could add type validation in the subclass:
public class StrBase : Base
{
private string propValue;
public override object prop {
get
{
return this.propValue;
}
set
{
if (value is string)
{
this.propValue = (string)value;
}
}
}
}
You could also expose a type-safe property in the subclass:
public class StrBase : Base
{
public string strProp {
get
{
return (string)this.prop;
}
set
{
this.prop = value;
}
}
}
This is possible since C# 9.0
Beginning with C# 9.0, override methods support covariant return types.
(see Microsoft docs)
public class First
{
private int someV;
public virtual object SomeV { get => someV; set => someV = (int)value; }
public First() { }
}
public class Two : First
{
private string someV;
public override object SomeV { get => someV; set => someV = value.ToString(); }
public Two() { }
}
and use of those:
First firstClass = new First();
firstClass.SomeV = 1;
Two twoClass = new Two();
twoClass.SomeV = "abcd";