I have two classes namely Class A and Class B(details below). They both have a method CreateDictionary which creates a dictionary of the properties in the class and returns the dictionary. Now as both the operations are I want to create generic method to do a code reuse.
public class A
{
public A(double a, double b, double c, string d, string key)
{
_a = a;
_b = b;
_c = c;
_d = d;
_key = key;
}
public string _key{ get; }
public double _d{ get; }
public double _c{ get; }
public double _b{ get; }
public string _a{ get; }
}
public Dictionary<string, A> AddEntry(double a, double b, double c, string d, string key)
{
Dictionary<string, A> _dictionary = new ();
if (!_dictionary.ContainsKey(key))
{
_dictionary.add(key, new A(a, b, c, d, key)
}
}
and here is the class B
public class B
{
public A(byte[] a, string key)
{
_a = a;
_key = key;
}
public byte[] _a{ get; }
public string _key{ get; }
}
public Dictionary<string, B> AddEntry(byte[] a, string key)
{
Dictionary<string, B> _dictionary = new ();
if (!_dictionary.ContainsKey(key))
{
_dictionary.add(key, new B(a, key)
}
}
Is there a way possible to create a utility class for the AddEntry Method.
Related
Consider the following class:
public interface IA{
int C { get; set;}
object Dummy(int A, int B);
}
public class A : IA
{
public int C {get; set;}
public object Dummy(int A, int B)
{
return new { A,B,C};
}
}
I do not understand how to moq such that the property is included in the returned object:
Mock<IA> mockedObject = new Mock<IA>();
mockedObject.SetUp(x => x.Dummy(It.IsAny<int>(),It.IsAny<int()).Returns((int A, int B) => { return new { A, B };// How do I return C along with A and B
I'm not even sure if it's possible, if it's not how should I be proceeding with such scenerio's?
I guess what you are looking for is something like:
using Moq;
using NUnit.Framework;
namespace TestUnitTests
{
public interface IA
{
int C { get; set; }
object Dummy(int A, int B);
}
public class A : IA
{
public int C { get; set; }
public object Dummy(int A, int B)
{
return new { A, B, C };
}
}
[TestFixture]
public class TestClass
{
private Mock<IA> _mockedObject;
[SetUp]
public void Setup()
{
_mockedObject = new Mock<IA>();
}
[Test]
public void Test()
{
const int A = 1;
const int B = 2;
const int C = 42;
_mockedObject.SetupGet(m => m.C).Returns(C);
ConfigureDummy(A, B);
var dummy = _mockedObject.Object.Dummy(A, B);
var expected = new { A, B, C };
Assert.That(dummy.ToString(), Is.EqualTo(expected.ToString()));
}
private void ConfigureDummy(int A, int B)
{
_mockedObject
.Setup(m => m.Dummy(A, B))
.Returns(new { A, B, _mockedObject.Object.C });
}
}
}
I have a class A and B like this :
public class B {
private A myA { get; }
public B(A a) {
myA = a;
}
}
public class A {
private B myB { get; }
public A(B b) {
myB = b;
}
}
I would like to know if it is possible, in one instruction, to instantiate an A and a B at the same time without having to use
B b = new B();
A a = new A(b);
b.SetA();
or
A a = null;
a = new A(new B(a));
The reason I want to be able to do this in one instruction is because I want to be able to instatiate a class of type A in the constructor of another class like this
public abstract class SuperClass() {
private A myA { get; }
public SuperClass(A a) {
myA = a;
}
}
public class SpecificClassWithKnownValuesOfA() : SuperClass {
public SpecificClassWithKnownValuesOfA() : base(/* here I want to use new A(new B(ref of a)) */) { }
}
Note that B.myA and A.myB are readonly properties as I don't want to put setters
I have to say that you can't do this. I understand that you want to prevent getting an A without B, and prevent getting a B without A.
I suggest using the factory pattern with a private constructor.
For A:
public class A
{
private B _b;
public A(B b)
{
_b = b;
}
}
For B, do not create a public constructor. Use a builder to build it, so every time you get a B, there is always a fine instance in it.
public class B
{
private A _a;
private B() { }
public (A, B) Init()
{
var b = new B();
_a = new A(b);
return (_a, b);
}
}
To get it, call:
var (a, b) = B.Init();
You could do this:
public class B {
private A myA { get; public set; }
public B() {}
public B(A a) {
myA = a;
a.B = this;
}
}
public class A {
private B myB { get; public set; }
public A(){}
public A(B b) {
myB = b;
b.A = this;
}
}
var a = new A(new B());
or alternatively
var b = new B(new A());
Whether its a good idea however is another question
You can like this :
public class B {
// This should be public with eventually a private setter
public A myA { get; private set; }
public B(A a) {
myA = a;
}
}
public class A {
public B myB { get; private set; }
public A() {
myB = new B(this);
}
}
And then
A a = new A();
I have multiple classes containing duplicated code, especially members and most important a static method that will create a new instance of the class and returning this instance: either a previously created instance registered in a dictionary or a new instance by calling the constructor.
An interface is no option, because I have the static method. I tried to solve the problem by introducing a base class that implements this static method, but I can not find a way to create and return a spefific child class properly.
Below is a code example of the current situation with class A and class B showing duplicated code.
public class A
{
private static readonly IDictionary<string, A> Registry = new Dictionary<string, A>();
public string Name { get; set; }
public A(string name)
{
this.Name = name;
}
public static A GetA(string instanceName)
{
lock (Registry)
{
if (!Registry.TryGetValue(instanceName, out var newInstance))
{
newInstance = new A(instanceName);
}
return newInstance;
}
}
}
And then in class B again there is a member Name and the GetX() Method.
public class B
{
private static readonly IDictionary<string, B> Registry = new Dictionary<string, B>();
public string Name { get; set; }
public B(string name)
{
this.Name = name;
}
public static B GetB(string instanceName)
{
lock (Registry)
{
if (!Registry.TryGetValue(instanceName, out var newInstance))
{
newInstance = new B(instanceName);
}
return newInstance;
}
}
}
Is there a possibility to avoid this kind of code duplication by introducing a base class or any other way?
This might be a little cleaner:
public class B: RegistryInstance<B>
{
public string Name { get; set; }
public B(string name)
{
this.Name = name;
}
}
public class A : RegistryInstance<A>
{
public string Name { get; set; }
public A(string name)
{
this.Name = name;
}
}
public abstract class RegistryInstance<T> where T:class
{
protected static readonly IDictionary<string, T> Registry = new Dictionary<string, T>();
public static T GetInstance(string instanceName)
{
lock (Registry)
{
if (!Registry.TryGetValue(instanceName, out var newInstance))
{
newInstance = (T)Activator.CreateInstance(typeof(T), new object[] { instanceName });
Registry.Add(instanceName, newInstance);
}
return newInstance;
}
}
}
Are you looking for a generic base class?
public abstract class BaseRegistryGetter<T>
{
private static readonly IDictionary<string, T> Registry = new Dictionary<string, T>();
public string Name { get; set; }
public BaseRegistryGetter(string name)
{
this.Name = name;
}
public static T GetValue (string instanceName, Func<string, T> creator) {
lock (Registry)
{
if (!Registry.TryGetValue(instanceName, out var newInstance))
{
newInstance = creator(instanceName);
}
return newInstance;
}
}
}
And then use it like this:
public class A : BaseRegistryGetter<A>
{
public A(string name) : base(name)
{
}
public static A GetA(string instanceName)
{
return BaseRegistryGetter<A>.GetValue(instanceName, s => new A(s));
}
}
The source for the awkward approach to make sure there is a string-constructor for A can be found here.
I think this should work. You can adapt it to fit your needs. Also, there was a bug in your code: you forgot to add to the Registry when you were creating a new instance.
class Program
{
static void Main(string[] args)
{
A a1 = A.GetInstance("a");
A a2 = A.GetInstance("aa");
A a3 = A.GetInstance("a");
B b1 = B.GetInstance("a");
B b2 = B.GetInstance("aa");
B b3 = B.GetInstance("a");
Console.WriteLine(a1 == a2); //false
Console.WriteLine(a1 == a3); //true
Console.WriteLine(b1 == b2); //false
Console.WriteLine(b1 == b3); //true
Console.ReadKey();
}
}
public class A : Generic<A>
{
public A(string name)
: base(name)
{
}
}
public class B : Generic<B>
{
public B(string name)
: base(name)
{
}
}
public abstract class Generic<T> where T : Generic<T>
{
private static readonly IDictionary<string, T> Registry = new Dictionary<string, T>();
public string Name { get; set; }
public Generic(string name)
{
this.Name = name;
}
public static T GetInstance(string instanceName)
{
lock (Registry)
{
if (!Registry.TryGetValue(instanceName, out var newInstance))
{
newInstance = (T)Activator.CreateInstance(typeof(T), instanceName);
Registry.Add(instanceName, newInstance);
}
return newInstance;
}
}
}
All the other answers try to solve this with generics, but it might be the case you wouldn't want to do this. First, it could be an unnecessary restriction further along that could end up causing variance issues. Second, it only solves one level of inheritance, if there is more, you are stuck again with the same problem:
class Base<T> { ... }
class A: Base<A> { ... }
class B: A { //How does the generic base class help? }
There are general solutions without the use generics that entails just a little code duplication. One could be the following:
public class Base
{
static readonly IDictionary<string, Base> Registry =
new Dictionary<string, Base>();
protected static Base GetBase(string instanceName,
Func<Base> creator)
{
lock (Registry)
{
if (!Registry.TryGetValue(instanceName, out var newInstance))
{
newInstance = creator();
}
return newInstance;
}
}
//...
}
And now yor derived types can impement a strongly typed delegated method:
public class A: Base
{
public A(string instanceName)
:base(instanceName)
{
}
public static A GetA(string instanceName)
=> GetBase(instanceName, () => new A(instanceName)) as A;
}
public class B: Base
{
public B(string instanceName)
:base(instanceName)
{
}
public static B GetB(string instanceName)
=> GetBase(instanceName, () => new B(instanceName)) as B;
}
I keep getting:
Array initializers can only be used in a variable or field
initializer. Try using a new expression instead.
I have no idea why. Is this not possible with C#. A similar construct works with simple types such as int or float.
public struct UnitObject
{
public float v;
public string t;
public string d;
}
public class UnitStandard
{
public UnitObject[] UnitDict = new UnitObject[] { { 1f, "s", "s" } };
}
Using .NET 4.5.
It's not completely clear how you expect that to work, but in c#, it's not valid syntax. You have two options:
Use a constructor
public struct UnitObject
{
public UnitObject(float v, string t, string d)
{
this.v = v;
this.t = t;
this.d = d;
}
}
public UnitObject[] UnitDict = new UnitObject[] { new UnitObject(1, "s", "s") };
Use the object initializer
public UnitObject[] UnitDict = new UnitObject[]
{
new UnitObject
{
v = 1,
t = "s",
d = "s"
}
};
As a side note: v, t and d are horrible names because they do not provide meaning and public members should follow PascalCase.
In order to follow the correct immutability pattern, use this:
public struct UnitObject
{
public float V { get; private set; }
public string T { get; private set; }
public string D { get; private set; }
public UnitObject(float v, string t, string d)
{
V = v;
T = t;
D = d;
}
}
I'm answering my own question here as I was advised this was the best way to help others - rather than editing the question.
I got this to work by adding a constructor:
public struct UnitObject
{
public float v;
public string t;
public string d;
public UnitObject(float val, string s1, string s2)
{
v = val; t = s1; d = s2;
}
}
public class UnitStandard
{
public UnitObject[] UnitDict = new UnitObject[] { new UnitObject( 1f, "s", "s" ) };
}
But Camilo's answer is much more elegant of course.
I have the following-
public Class A
{
public int a;
public List<String> list;
}
public class B
{
public int a;
public string b;
}
A instanceofA;
B someB = new B()
{
a = 1,
b = "SomeString"
};
instanceofA= new A()
{
a = someB.a,
list = new List(){B}
};
return instanceofA;
The reason why i am converting string to List<String> is to pass it on to the UI layer and render it as drop down menu.
How to get the string b to the List<String> variable?
B.ToList() converts B into a character array.
Do you want to put the b-property of your B-class into a list? Then you need the b-member to be added to the list, not your instance of B.
A instanceofA;
B someB= new B()
{
a=1,
b="SomeString"
};
instanceofA = new A()
{
a=someB.a,
list = new List<string> {someB.b }
};
You need to add the string member b to the list, not the entire class instance of B (which is not a string, because it is a B).
public Class A
{
public int a;
public List<String> list = new List<String>();
}
public Class B
{
public int a;
public string b;
}
public A someMethod()
{
B someB = new B()
{
a=1,
b="SomeString"
};
A instanceofA = new A();
instanceofA.a = someB.a;
instanceofA.list.add(someB.b);
return instanceofA;
}
You can do this(This question is not clear)
public class A{
public A()
{
this.list=new List<string>();
}
public List<String> list;
}
then A.list.Add();
If you wants add b to A list
public class A{
public List<B> BList;
}
A.BList.Add();