public class Foo
{
Bar Field{get;set;}
}
public class Bar
{
public int Value{get;set};
public int Value2{get;set;}
}
Is it possible to do something like that in C# :
Foo a = new Foo();
a.Value = 5;
a.Value2 = 8;
In the other words, is there possibility to publish fields of Bar class as if Bar was a Base Class?
Since you have a Bar type property in your class Foo, you have composition. You can access the Fields through that property like:
Foo a = new Foo();
a.Field.Value = 1;
a.Field.Value2 = 2;
But you have to modify your current code like:
public class Foo
{
public Bar Field { get; set; } //make the property public
}
public class Bar
{
public int Value { get; set; }
public int Value2 { get; set; }
}
The other option is to inherit Bar in Foo like:
public class Foo : Bar
{
public int FooID { get; set; }
}
And then you can access Bar's field directly like:
Foo a = new Foo();
a.Value = 1;
a.Value2 = 2;
Not directly, but you can add properties to the "outer" class to expose them explicitely.
public class Foo
{
Bar Field{get;set;}
public int Value{get { return Field.Value;} }
public int Value2{get { return Field.Value2;} }
}
public class Bar
{
public int Value{get;set};
public int Value2{get;set;}
}
However, this of course is not very handy. If you really want to have something like this more "automatically", you probalby could do it with dynamic and custom TypeDescriptors, but that in turn will prevent compile-time type and member verification.. I don't recommend that until you absolutelyhave to.
Related
Say I have this object
public class foo
{
Ibar data {get; set;}
}
public interface Ibar
{
int id { get; set; }
}
public class bar : Ibar
{
public int id {get; set;}
public string a {get; set;}
}
public class bar2 : Ibar
{
public int id {get; set;}
public DateTime b {get; set;}
}
Now I implement a method like this one here
public something Method(foo f)
{
if(f.data is bar)
Console.WriteLine(((bar)f.data).doSomething());
else
Console.WriteLine(((bar2)f.data).doSomething());
}
public string doSomething(this bar b)
{
return b.a;
}
public string doSomething(this bar2 b)
{
return b.b.ToString();
}
So far so good (see). Is there a way to make this part here more elegant? in particular if I have more than one implementations of Ibar, it gets messy...
if(f.data is bar)
Console.WriteLine(((bar)f.data).doSomething());
else
Console.WriteLine(((bar2)f.data).doSomething());
UPDATE
So doSomething should be an extension method. That's why it isn't defined in the interface. So in other words: Im not allowed to change the interface or their implementations.
Are you trying to make dedicated extention class?
assuming you are doing so.
however you can achieve your goal with dynamic
public static class BarExtensions
{
public static string Something(this Ibar b)
{
return doSomething((dynamic)b);
}
public static string doSomething( bar b)
{
return b.a;
}
public static string doSomething(bar2 b)
{
return b.b.ToString();
}
}
so, you will required to call Something only, with Proper Type.
Here Type can be easily get by .GetType() of any object (so it won't be a problem)
I think you can do the type checks in one place because this is a good candidate for polymorphism. Since both bar and bar2 implement Ibar, you can change the definition of doSomething to the following.
public string doSomething(Ibar item)
{
return item is bar ? ((bar)item).a : ((bar2)item).b.ToString();
}
Now when you want to display it, this is how you handle your foo:
public void Method(foo f)
{
Console.WriteLine(f.data);
}
You just pass in the data property because the doSomething will know what to do with it when it receives it.
Update
Based on your comment, I'm expanding the code to use pattern matching as I suggested. Consider the following
public string doSomething(Ibar item)
{
switch (item)
{
case bar b:
return b.a;
case bar2 b:
return b.b.ToString();
case barX b:
return b.X.ToString();
default:
return item.GetType().ToString(); // Just in case...
}
}
where the definition of barX is
public class barX : Ibar
{
public int id {get; set; }
public object X {get; set; }
}
So whenever you add an implementation of Ibar, you cater for it in doSomething. All client code will remain unchanged because all they have to do is pass an Ibar to the doSomething method which uses pattern matching in the last example to determine what type the item is and it acts accordingly.
Final Edit
Seeing as you want to use overloads, you can use reflection but I don't know if that will qualify for your definition of elegant. In this case, it will not use switch statements and will find your methods as long as they are in the type this one is written in. Consider the following and change the defintion of my previously supplied DoSomething.
public static string ProcessThings(Ibar item)
{
var theType = item.GetType();
Console.WriteLine(theType.Name);
MethodInfo method = typeof(Program).GetMethods()
.Where(x => x.IsStatic && x.Name == "DoSomething" && x.ToString().Contains(theType.Name))
.SingleOrDefault();
var ret = method.Invoke(null, new object[] { item });
return ret?.ToString();
}
public static string DoSomething(barX item)
{
return "foo";
}
public static string DoSomething(bar2 item)
{
return "bar";
}
This way, you call the ProcessThings method (renamed for brevity but it can still stay as DoSomething) and it will figure out which one of your overloads to call.
If I remember well you can play with generic type constraints like this:
public something Method<T>(T f) where T : IBar
{
//Stuff here, where assures you f is always IBar
}
This should force the incoming parameter to be of the type you want.
This is the most elegant way I could think of.
Other are typeof and other conditional statements, which would require more in-method code anyway (if, else and so on).
EDIT:
Since OP seems having a hard time to understand I wrote a fully working code sample with Microsoft Unit Testing result.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests_ALL
{
[TestClass]
public class UnrelatedTests
{
[TestMethod]
public void InterfaceTest()
{
bar x = new bar { result = "Hi bar it's " };
bar2 xx = new bar2 { beforeResult = DateTime.Now };
Console.WriteLine(Method(x));
Console.WriteLine(Method(xx));
}
public string Method<T>(T f) where T : Ibar
{
return f.result;
}
}
public class foo
{
public foo(Ibar fooBar)
{
data = fooBar;
}
Ibar data { get; set; }
}
public interface Ibar
{
int id { get; set; }
string result { get; set; }
}
public class bar : Ibar
{
public int id { get; set; }
public string result { get; set; }
}
public class bar2 : Ibar
{
public int id { get; set; }
public DateTime beforeResult
{
set { result = value.ToString(); }
}
public string result { get; set; }
}
public static class Extensions
{
public static string doSomething(this bar b)
{
return b.result;
}
public static string doSomething(this bar2 b)
{
return b.result;
}
}
}
Here's the output:
I am trying to populate an array of objects that inherit from IFoo. The problem I am facing is that structure map is populating the property within IFoo with the same instance of IBar. I cannot add AlwaysUnique() to IBar because this is used elsewhere in our enterprise application and would have consequences.
Is there anyway that I can get it to create new instances of the Bar object for every Foo in the collection?
public interface IFoo
{
IBar bar { get; set; }
}
public class Foo1 : IFoo
{
public IBar bar { get; set; }
public Foo1(IBar bar) { this.bar = bar; }
}
public class Foo2 : IFoo
{
public IBar bar { get; set; }
public Foo2(IBar bar) { this.bar = bar; }
}
public interface IBar
{
Guid id { get; set; }
}
public class Bar : IBar
{
public Guid id { get; set; }
public Bar() {this.id = Guid.NewGuid();}
}
class Program
{
static void Main(string[] args)
{
var container = new Container(_ =>
{
_.Scan(x =>
{
x.TheCallingAssembly();
x.AddAllTypesOf<IFoo>();
});
_.For<IBar>().Use<Bar>(); //I can't change this line because Bar is used elsewhere in the project
});
var foos = container.GetAllInstances<IFoo>();
if (foos.ElementAt(0).bar == foos.ElementAt(1).bar)
throw new Exception("Bar must be a different instance");
}
}
You could do this with a custom policy. See example 3 here, you could adapt that to your needs.
Something like:
public class BarUniqueForFoo : IInstancePolicy
{
public void Apply(Type pluginType, Instance instance)
{
if (pluginType == typeof(IBar) && instance.ReturnedType == typeof(Bar)
{
instance.SetLifecycleTo<UniquePerRequestLifecycle>();
}
}
}
assuming that i have below class:
public class ClassA
{
public string ElementA { get; }
public string ElementB { get; }
}
public class ClassB
{
public ClassA ElementC = new ClassA()
{
ElementA = "Sample Value A",
ElementB = "Sample Value B"
};
public ClassB ElementD = new ClassA()
{
ElementA = "Sample Value C",
ElementB = "Sample Value D"
};
}
how can i nest ClassA inside and as an element of ClassB with only a { get; } property. I am trying to instantiate a class where it can only be accessed via the { get; } assessor as i want it to behave as a fixed variable/value. the IDE (Visual Studio) throws me an error whenever i try this approach which states:
Property or indexer 'ClassA.ElementA' cannot be assigned to -- it is
read only
writing ClassA as:
public class ClassA
{
public string ElementA { get; set; }
public string ElementB { get; set; }
}
makes ClassB's ClassA Element editable but does not throw an error in the IDE (Visual Studio).
how or is it possible to do something of my idea ? Thanks.
If you don't want the properties modified from outside of the class, add a private setter and modify the class's constructor to set the values upon instantiation:
public class ClassA
{
public ClassA(string elementA, string elementB)
{
ElementA = elementA;
ElementB = elementB;
}
public string ElementA { get; private set; }
public string ElementB { get; private set; }
}
Then instantiate it from ClassB like this:
public class ClassB
{
public ClassA ElementC = new ClassA("Sample Value A", "Sample Value B");
}
A property defined like this:
public Foo Bar { get; }
Is equivalent to this:
private readonly Foo bar;
public Foo Bar { get { return this.bar; } }
The readonly keyword means the field can only be assigned in a class's constructor (or the field initialization list, which is executed before the constructor method's body).
Because the field is private, you cannot set it from outside the type's access scope, and because it's a readonly field it must be in the constructor - so to use an externally-provided value you must use a constructor parameter:
public ClassA(Foo value) {
this.Bar = value;
}
I have an arbitrary amount of classes, classThatInherits, anotherClassThatInherits, etc. that inherit classToBeInherited.
I then have a method, b, that needs to be able to access myValue from the classes that inherit classToBeInherited. How can I achieve this, without casting?
//This class will be inherited by other classes
public class classToBeInherited {
public bool isSomething { get; set; }
}
//This class with inherit 'classToBeInherited'
public class classThatInherits : classToBeInherited {
public int myValue { get; set; } //this needs to be accessable...
}
//...And so will this class
public class anotherClassThatInherits : classToBeInherited {
public int myValue { get; set; }
}
private class normalClass {
private void a() {
classThatInherits cti = new classThatInherits();
b(cti);
anotherClassThatInherits acti = new anotherClassThatInherits();
b(acti);
}
private void b(classToBeInherited c) {
//***
//get myValue from the classes that inherit classToBeInherited
//***
}
}
Move myValue to classToBeInherited:
public class classToBeInherited {
public bool isSomething { get; set; }
public abstract int myValue { get; set; }
}
Then in classThatInherits and anotherClassThatInherits use public override int myValue { get; set; } to implement that property.
Ofcorse, if myValue is needed in only some of the classes, then you can have virtual and not abstract property.
var a = c as anotherClassThatInherits;
if (a != null)
{
var myValue = a.myValue;
}
I don't know why you don't want to do casting, but it's very common to have code like above.
UPDATED
If you really don't want casting, you can use reflection (but you still need to know the type of anotherClassThatInherits)
var getter = typeof(anotherClassThatInherits).GetProperty("myValue").GetGetMethod();
var myValue = getter.Invoke(c, null);
I have the following:
public abstract class FooBase
{
public virtual int Id { get; set; }
}
public class Foo1 : FooBase { /* could be stuff here */ }
public class Foo2 : FooBase { /* could be stuff here */ }
public class Bar
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual SOMETHING WhichFoo { get; set }
}
...where WhichFoo deals with which FooBase to use (potentially string of "Foo1" but this seems quite messy).
With mappings:
public class FooBaseMap : ClassMap<FooBase>
{
public FooBaseMap()
{
this.Id(x => x.Id);
this.DiscriminateSubClassesOnColumn("Type");
}
}
public class Foo1Map : SubclassMap<Foo1>
{
public Foo1Map() { this.DiscriminatorValue("Foo1"); }
}
public class Foo2Map : SubclassMap<Foo2>
{
public Foo2Map() { this.DiscriminatorValue("Foo2"); }
}
What I want to be able to do is to create a new Foo, either 1 or 2, based on a value stored in Bar. So:
Bar bar = this.Session.Get<Bar>(1);
FooBase foo1 = bar.GetANewFoo(); // returns a new Foo1
Bar anotherBar = this.Session.Get<Bar>(123);
FooBase foo2 = bar.GetANewFoo(); // returns a new Foo2
Where GetANewFoo() could be a method, a property which returns an empty instance of Foo1 or Foo2.
Effectively what I want to do is to store the type of FooBase to be created by GetANewFoo in Bar.
What's the best way of going about this without explicitly having to manually write "Foo1" or "Foo2" to a Bar when I create one?
You can create a column in the Bar table which is going to save what kind of Foo it is. So, if this SOMETHING type of property is an enum, or a string, or an int (whatever), you can use switch-case statement to identify the kind of Foo, create what you need and return.
Just like this:
public FooBase GetANewFoo()
{
switch (WhichFoo)
{
case "Foo1": return new Foo1();
case "Foo2": return new Foo2();
default: return null;
}
}
Okay I think I got it - actually rehashing a method I used for the Strategy Pattern.
public abstract class FooFactoryBase
{
protected FooFactoryBase() { } // for NHibernate
protected FooFactoryBase(Guid id)
{
this.Id = id;
}
public virtual Guid Id { get; set; }
public virtual IList<Bar> Bars { get; set; }
public abstract FooBase CreateFoo();
}
public class Foo1Factory : FooFactoryBase
{
public readonly static Guid Guid = new Guid("abc123...");
public Foo1Factory() : base(Guid) { }
public override FooBase CreateFoo()
{
return new Foo1();
}
}
Then Bar becomes:
public class Bar
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual FooFactoryBase FooFactory { get; set; }
}
And mappings:
public class BarMap : ClassMap<Bar>
{
this.Id(x => x.Id);
this.Map(x => x.Name);
this.References(x => x.FooFactory);
}
public class FooFactoryBaseMap : ClassMap<FooFactoryBase>
{
this.Id(x => x.Id);
this.HasMany(x => x.Bars).Inverse();
this.DiscriminateSubClassesOnColumn("Id");
}
public class Foo1FactoryMap : SubClassMap<Foo1Factory>
{
this.DiscriminatorValue(Foo1Factory.Guid);
}
Now when I create my database I can populate it with all my FooFactorys, when adding Bars I can just load the appropriate Factory from the database and then call my code like so:
Bar bar = this.Session.Get<Bar>(10);
FooBase foo = bar.FooFactory.CreateFoo();
and the appropriate FooBase will be created.
Sometimes you just need to ask the question to figure it out :)