I have a class with two constructors:
public class Foo
{
public Foo(string bar = "hello"){
}
public Foo(string bar = "hello", string barrier = "world"){
}
}
Now, when I want to call the constructor with 1 parameter, I can call:
new Foo();
But I'm getting an ambiguous reference error because Visual Studio doesn't know which constructor I want to use. How can I specify which constructor I want without passing parameters?
To solve the ambiguity, you should make the second method have a required parameter:
public class Foo
{
public Foo(string bar = "hello"){
}
public Foo(string bar, string barrier = "world"){
}
}
That is the only way to make the method resolution deterministic.
But as noted already, that default parameter is useless, since in any other case it will drop to the second constructor. A better option is to drop the first constructor, but if that works out depends on the implementation inside:
public class Foo
{
public Foo(string bar = "hello", string barrier = "world"){
}
}
The point of default values is to reduce the number of methods, just have
public class Foo
{
public Foo(string bar = "hello", string barrier = "world"){
}
}
and set whatever defaults you need for the call, Foo is a single class that should handle all the defaults otherwise its seems it's being used for different purposes
Just make one method that checks both params for string.isNullOrEmpty
static void Main(string[] args)
{
testme("DD", "jj");
Console.ReadLine();
}
public static void testme(string d="", string s = "")
{
if (string.IsNullOrWhiteSpace(d) && string.IsNullOrWhiteSpace(s))
return;
if(string.IsNullOrEmpty(d))
Console.Write(s);
if (string.IsNullOrEmpty(s))
Console.Write(d);
}
It can be solved quite simply like this, using just one constructor. I've added some extra code to faciliate a simple demonstration:
public class Foo
{
private string _bar;
private string _barrier;
public Foo(string bar = "hello", string barrier = "world"){
_bar = bar;
_barrier = barrier;
}
public void show()
{
Console.WriteLine("_bar = " + _bar + " , _barrier = " + _barrier);
}
}
Then all of these combinations are valid...
Foo a = new Foo();
a.show();
Foo b = new Foo("b");
b.show();
Foo c = new Foo(barrier: "c");
c.show();
Foo d = new Foo("d", "e");
d.show();
...and result in the following output:
_bar = hello , _barrier = world
_bar = b , _barrier = world
_bar = hello , _barrier = c
_bar = d , _barrier = e
Maybe you don't need public constructors? Try something like this:
class Program
{
static void Main (string[] args)
{
var person = Person.FromName ();
}
}
public class Person
{
private Person (string name, string surname) { }
public static Person FromName (string name = "John") => new Person (name, "Smith");
public static Person FromFullName (string name = "John", string surname = "Smith") => new Person (name, surname);
}
Of course Person class is just an example (bad example :P) but you should get the idea.
Related
Simply put how do you establish a connection between method variable decloration and connect it with class properties (or inner objects), lets say you have default or hard set values in a class like this (obviously they could be other types but for simplicity its set to strings) :
public class SampleClass
{
public string strA = "Something 1";
public string strB = "Something 2";
public string strC = "Something 3";
}
//think of it as a data layer where strings are pointers to dbSets
How do you leverage the same SampleClass in a method that allows ONLY pick of properties Method(property).
Easy sample that does what its supposed to:
public class ProccessClass
{
private string _dummyOut;
public ProccessClass Pick(string input)
{
this._dummyOut = input;
return this;
}
}
class Program
{
static void Main(string[] args)
{
var Test = new ProccessClass().Pick(new SampleClass().strB);
// we know this works and compiles and returns the strB
}
}
What would you have to convert to ommit the new instantiation and skip the class declaration (if possible but in theory should be doable)
new SampleClass().strB
needs to be just
strB
So how to get the final code to execute??
public class SampleClass
{
public string strA = "Something 1";
public string strB = "Something 2";
public string strC = "Something 3";
}
public class ProccessClass
{
private string _dummyOut;
public ProccessClass Pick(SampleClass sampleClass) //is it the variable declaration?
{
this._dummyOut = input;
return this;
}
}
class Program
{
static void Main(string[] args)
{
string Test = new ProccessClass().Pick(strB);
//so NO new keywords clean and easy set based on class provided above
}
}
Constructor and void setters but no go, the goal is to set the Hard relation ship between the method intake value and setters
In repository I keep some instances which live throughout the lifetime of my application but sometimes I need an immediate replacement for such instance with another instance and LightInject even if passing the new instance to the container.GetInstance constructor override.
Here is a snippet showing the problem:
internal class ClassA
{
public string Name { get; private set; }
public ClassA(string name)
{
Name = name;
}
public override string ToString()
{
return Name;
}
}
internal class ClassB
{
public ClassA A { get; private set; }
public ClassB(ClassA a)
{
A = a;
}
public override string ToString()
{
return string.Format("I contain {0}", A);
}
}
private void TestContainer()
{
var container = new LightInject.ServiceContainer();
var a1 = new ClassA("A instance 1");
container.Register(x => a1);
container.Register<ClassB>();
var a2 = new ClassA("A instance 2");
var bwitha1 = container.GetInstance<ClassB>();
if(bwitha1.A != a1)
{
throw new InvalidOperationException("This will not happen");
}
var bwitha2 = container.GetInstance<ClassA, ClassB>(a2);
if(bwitha2.A != a2)
{
throw new InvalidOperationException("Something went wrong here");
}
}
Why LightInject previously registered instance takes precedence if I give explicit instance in GetInstance call? How to get around the issue and construct the object with an alternative instance of one of the arguments?
In the current version of LightInject you need to provide a factory if you want to use runtime arguments.
The following workaround might work for you.
using LightInject;
class Program
{
static void Main(string[] args)
{
var container = new ServiceContainer();
container.Register<Bar>();
container.Register<Foo>();
container.Register<Bar, Foo>((factory, bar) => new Foo(bar), "FooWithRuntimeArgument");
var instance = container.GetInstance<Foo>();
var instanceWithRuntimeArgument = container.GetInstance<Bar, Foo>(new Bar(), "FooWithRuntimeArgument");
}
}
public class Foo
{
public Foo(Bar bar) {}
}
public class Bar {}
I want to access a string from one class to another. I have used the property method as follows -
Myclass.cs
public class MyClass
{
private string _user;
public string user
{ get { return this._user; } set { this._user = value; } }
}
consumption.aspx.cs
I am assigning the value to user in a function
MyClass m = new MyClass();
m.user = "abc"
Now when I try to use this value in my another function which is called after this value is assigned
RawDal.cs
MyClass m = new MyClass();
string x = m.user;
I get empty value... How to do it?
As already mentioned in the comments you are creating two separate instances of MyClass which results simplified in something like:
int a;
a = 3;
int b;
Console.WriteLine("a: " + b); //<-- here it should be obvious why b is not 3
You can work around this in 3 ways:
1) Use the same instance of MyClass for the second call, but in this case you need to be in the same scope or pass the instance on to the new scope.
2) Make the property/member static:
public class MyClass
{
public static string User { get; set; } //the "static" is the important keyword, I just used the alternative property declaration to keep it shorter
}
Then you can access the same User value everywhere via MyClass.User.
3) Use a singleton:
public class MyClass
{
private static MyClass instance = null;
public static MyClass Instance
{
get
{
if(instance == null)
instance = new MyClass();
return instance;
}
}
public string User { get; set; }
}
Then you can access it via MyClass.Instance.User.
There are possibly some more solutions, but these are the common ones.
You are not using the same instance. Try
public class MyClass
{
private string _user;
public string user
{ get { return this._user; } set { this._user = value; } }
}
public string YourFunction()
{
MyClass m = new MyClass();
m.user = "abc"
return m.user;
}
If all you want to return is a string try something like
string x = YourFunction();
The business object is Foo.cs
What if Foo`s properties run custom logic? Would it then not a bad idea to create Foo objects which could change the data inside the Foo object and it returns values I do not expect?!
public class FooBuilder
{
private string bar = "defaultBar";
private string baz = "defaultBaz";
private string bling = "defaultBling";
public FooBuilder Bar(string value)
{
bar = value;
return this;
}
public FooBuilder Baz(string value)
{
baz = value;
return this;
}
public FooBuilder Bling(string value)
{
bling = value;
return this;
}
public Foo Build()
{
return new Foo {Bar = bar, Baz = baz, Bling = bling};
}
}
If I understand what you are asking...
It is ok for proprties to execute some code more than setting a backing fields. However if you set a property to one value and then use the getter and discover that it has returned a different value to what you set then that is unexpected. So either this should be avoided within properties or use methods that provide descriptive meaning as to the behaviour/data change.
so this IMO is bad
var foo = new Foo();
foo.Bar = "hello bar";
string bar = foo.Bar;
Console.WriteLine(bar); // if this does not print "hello bar" then it is bad/unexpected
How would you share the same object between two other objects? For instance, I'd like something in that flavor:
class A
{
private string foo_; // It could be any other class/struct too (Vector3, Matrix...)
public A (string shared)
{
this.foo_ = shared;
}
public void Bar()
{
this.foo_ = "changed";
}
}
...
// inside main
string str = "test";
A a = new A(str);
Console.WriteLine(str); // "test"
a.Bar();
Console.WriteLine(str); // I get "test" instead of "changed"... :(
Here, I don't want to give a ref to the Bar method. What I want to achieve is something that would look like that in C++:
class A
{
int* i;
public:
A(int* val);
};
A::A (int* val)
{
this->i = val;
}
I read there is some ref/out stuff, but I couldn't get what I'm asking here. I could only apply some changes in the methods scope where I was using ref/out arguments...
I also read we could use pointers, but is there no other way to do it?
This has nothing to do with sharing objects. You passed a reference to a string into the A constructor. That reference was copied into the private member foo_. Later, you called B(), which changed foo_ to "changed".
At no time did you modify str. str is a local variable in main. You never passed a reference to it.
If you had wanted to change str, you could have defined B as
public void Bar(ref string s)
{
this.foo_ = "changed";
s = this.foo_;
}
Consider:
public class C
{
public int Property {get;set;}
}
public class A
{
private C _c;
public A(C c){_c = c;}
public void ChangeC(int n) {_c.Property = n;}
}
public class B
{
private C _c;
public B(C c){_c = c;}
public void ChangeC(int n) {_c.Property = n;}
}
in main:
C myC = new C() {Property = 1;}
A myA = new A(myC);
B myB = new B(myC);
int i1 = myC.Property; // 1
myA.ChangeC(2);
int i2 = myC.Property; // 2
myB.ChangeC(3);
int i3 = myC.Property; // 3
Wrap your string inside a class. You need to do this because strings are immutable. Any attempt to change a string actually results in a new string.
class Foo {
class StringHolder {
public string Value { get; set; }
}
private StringHolder holder = new StringHolder();
public string Value {
get { return holder.Value; }
set { holder.Value = value; }
}
public Foo() { }
// this constructor creates a "linked" Foo
public Foo(Foo other) { this.holder = other.holder; }
}
// .. later ...
Foo a = new Foo { Value = "moose" };
Foo b = new Foo(a); // link b to a
b.Value = "elk";
// now a.Value also == "elk"
a.Value = "deer";
// now b.Value also == "deer"
I would split my answer to 2 parts:
1) If the variable is a reference type than it is already shared since you pass its reference to all interested objects. The only thing you should pay attention is that the reference type instances are mutable.
2) If the variable is a value type than you would have to use ref or out or some wrapper that is mutable and you can change the value inside the wrapper using a method or a property.
Hope that helps.
You need to pass the paramter as a reference to your method,
class A
{
private string foo_; // It could be any other class/struct too (Vector3, Matrix...)
public A(string shared)
{
this.foo_ = shared;
}
public void Bar(ref string myString)
{
myString = "changed";
}
}
static void Main()
{
string str = "test";
A a = new A(str);
Console.WriteLine(str); // "test"
a.Bar(ref str);
Console.WriteLine(str);
}
When a variable is a string, it is a reference.
Try to clone the string. http://msdn.microsoft.com/en-us/library/system.string.clone.aspx