I am relatively new in C#.
I am trying to understand how the flowing bit of code is working.
public static int Method3()
{
//some code
If(Class1.Method1(int Variable1).Method2(Class3 Variable2))
{
//even more code
}
//some code
}
OK, now a bit of context.
This if-statement is in Method3 and Method3 is the Class Class1.
Method1 takes an Int value and returns NULL or an Class Class2.
Method2 takes a Class lets call it Class3 and it returns true or false.
So I understand for the if-statement to be valid the condition must return true or false.
Which will come from the Method2 from my understanding.
But what is Method1 doing here?
What happens with the output of Method1?
Does it have any influence to the condition?
I hope you guys can understand what I mean.
If not please ask.
It would be far easier to understand if you get an example with more meaninful names.
Warning: This code and the one in your question is vulnerable to NullReferenceException. If GetClient returns null, you will have an exception.
For example:
public static bool SellingExample1()
{
int clientId = 21;
// Possible NullReferenceException
if(Shop.GetClient(clientId).OwesMoney())
{
// Send warning email to sales manager
}
// Do selling logic
}
public static bool SellingExample2()
{
int clientId = 21;
Client clientToSell = Shop.GetClient(clientId);
if (clientToSell == null) return false; // Check to avoid NullReferenceException before calling methods on a null object.
bool clientOwesMoney = clientToSell.OwesMoney();
if(clientOwesMoney)
{
// Send warning email to sales manager
}
// Do selling logic
}
public class Shop
{
public static Client GetClient(int clientId)
{
// Look the database and return the client
}
}
public class Client
{
public int Id { get; set; }
public string Name { get; set; }
public bool OwesMoney()
{
// Return true if there are unpaid bills
}
}
A method doesn't take a class. It takes an instance of a class.
Think of a class as a description of a thing and an instance as a specific thing of that kind, e.g. Cat might be a class where "Tom the cat" might be an instance.
The picture is a little more complex because methods can be static meaning they belong with the class or not, meaning they belong with the instance. In the following, I'll assume you are dealing with static methods because the method in your example is static.
Because you are chaining method calls, I assume Method1 returns something (an object instance) you can call Method2 on.
Now let's look at how your code might be modified given that understanding:
public static int Method3()
{
//some code
int Variable1 = 42;
Class3 Variable2 = new Class3();
if(Class1.Method1(Variable1).Method2(Variable2))
{
//even more code
}
//some code
}
Related
I have a class that contains several methods eg.:
class mySqlTool{
private string _values, _table, _condition, _result;
public mySqlTool Select(string values = null){
//this is REQUIRED
_values = string.Format("select {0} ", values);
return this;
}
public mySqlTool Update(string table){
//this is REQUIRED
_table = table;
return this;
}
public mySqlTool Set(string name, String value){
//this is REQUIRED
//handle name and value
return this;
}
public mySqlTool From(string table = null){
//this is REQUIRED
_table = table;
return this;
}
public mySqlTool Where(string condition = null){
//this is OPTIONAL
_condition = condition;
return this;
}
public string Execute(){
//this is REQUIRED
//this is samplecode, of course here is checked if its select or update
//but to keep it short i erased it
statement = string.Format("{0} {1}", _values, _table);
if (!string.IsNullOrEmpty(_condition))
{
statement += string.Format(" where {0}", _condition);
}
//do some with statemen and fill result
return _result;
}
}
now I use this in this chaining way:
MySqlTool t = new MySqlTool();
string result = t.Select("a,b,c").From("x").Where("foo=bar").Execute();
My VS provides me with available methods when I hit DOT (.).
My problem is, I want to denie to use some methods before other methods have been used eg:
MySqlTool.Where().Select().From().Execute();
In this case .C() should not be callable befor .A() was called. So to clarify whats allowed and whats not, here a small list
//Allowed
t.Select().From().Execute();
t.Select().From().Where().Execute();
t.Update().Set().Set().Set().Where().Where().Where().Execute();
//not Allowed
t.Select().Where().Execute();
t.Select().Select().Select().From().Execute();
t.From()...
t.Where()...
t.Execute()....
I read some about interfaces and also about state but I'm not sure if this is what im searching for.
So my question:
Is this what I want even possible?
If yes, how is this technique called?
General description - see end for specific comments
Is this what I want even possible?
Not within the same class, no. How would the compiler know what you'd already called? (Imagine you had a method with a parameter of type Test - what methods should be available to call on that?) The type system decides what's valid and what's not - so if there are different sets of valid operations, that suggests different types.
What you can do is have different types representing the different states, which will only include the appropriate methods for state transitions. So you could have something like this:
class Test0 // Initial state
{
public Test1 A() { ... }
}
class Test1 // After calling A
{
public Test2 B() { ... }
}
class Test2 // After calling B
{
// This returns the same type, so you can call B multiple times
public Test2 B() { ... }
// This returns the same type, so you can call C multiple times
public Test2 C() { ... }
public string DoSomething() { ... }
}
Then you can use:
Test0 t = new Test0();
string x1 = t.A().B().DoSome();
string x2 = t.A().B().C().DoSome();
string x3 = t.A().B().B().B().C().C().C().DoSome();
... but your invalid cases wouldn't compile.
It works, but it's pretty ugly. Without knowing what the methods are meant to achieve, it's hard to suggest anything else - but in many cases a single method with optional parameters may be better, or possibly a builder pattern.
An alternative is to use a single class and validate the calls at execution time instead, of at compile time. That's less helpful when coding, but avoids having a huge mess of types.
Yet another alternative would be to have a single class - and create a single instance - but use interfaces to represent the state. Your class would implement all the interfaces, so it could still just return this:
interface IStart
{
IMiddle A();
}
interface IMiddle
{
IFinal B();
}
interface IFinal
{
IFinal B();
IFinal C();
string DoSomething();
}
class Test : IStart, IMiddle, IFinal
{
public IMiddle A(string x = null) { return this; }
public IFinal B(string x = null) { return this; }
public IFinal C(string x = null) { return this; }
public string DoSomethign { ... }
}
Then you'd have:
IStart t = new Test();
string x1 = t.A().B().DoSome();
string x2 = t.A().B().C().DoSome();
string x3 = t.A().B().B().B().C().C().C().DoSome();
But this feels pretty wrong to me. I'd expect the A, B and C methods to be effectively changing state in some way - so having separate types would indicate which state is available. In the first example, a Test0 definitely doesn't have the state provided by the A call, but a Test1 does... and a Test2 instance has state provided by A and B, and possibly C.
Specific example
For the specific example given, I'd probably just make the constructor handle the required information (the table name) and use properties/indexers for the rest. I'd probably separate out a query command from updates:
SqlQuery query = new SqlQuery("table")
{
Columns = { "a", "b", "c" },
Where = { "foo=bar" } // Not sure how you're parameterizing these
};
And:
SqlUpdate update = new SqlUpdate("table")
{
// Which columns to update with which values
["a"] = 10,
["b"] = 20,
Where = { "foo=bar" } // Not sure how you're parameterizing these
};
In each case there'd be an Execute method returning the appropriate results.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Sometimes it happens that I want to use a lot of Method As variables in Method B.
Usually its quite a pain to pass all the variables to this method, especially if I have to do this a lot of times (but cannot simply copy paste, because some things change) or am just to lazy.
Is there such a thing like a "inner Method"? Or some concept to handle this in an easy way?
What I want to do:
public void A()
{
int a = 4;
string b = "Hello World";
B(ref vals);
//Or like so
C(ref current);
}
public void B(ref AllValues)
{
a = 3;
...
}
public void C(ref MethodThatSharesAllValues method)
{
method.a = 3;
...
}
If they all are in the same class
You can configure them as class variables:
public class MyClass{
//set this as private/protected/public or nothing and you can also set a default value
int a;
public void A()
{
a = 4;
string b = "Hello World";
B();
C();
}
public void B()
{
a = 3;
...
}
public void C()
{
a = 3;
...
}
}
Elseway
public static class MyClassA{
public static int a = 0;
public static void MethodA(){
this.a = 3;
}
}
now from method B you can access MyClassA
int myExValueA = MyClassA.a;
Elseway you gotta pass them as parameters
hope this helps
You can create a class which will hold your parameters and then pass only an instance of this class
public void metA(Parameters input)
{
input.a = 5;
input.c = "hello";
metB(input);
}
public void metB(Parameters input)
{
input.b = 10;
}
public class Parameters
{
public int a;
public int b;
public string c;
}
You can declare the variables static in a class header and use them as you like, private if are in the same class, protected for child classes, internal or public else. Or box the variables in a class like this:
public class Foo
{
public int A { get; set; }
public int B { get; set; }
public string C { get; set; }
}
If passed variables are the same type you can use data structure like int[] or string[] or List<int> or List<string> and pass them without ref but this has the disadvantage that more than often you would not use all varibales from the structure as it is also the case with the class boxing variant.
Something like the following:
public void foo() {
int a = 10;
// ...
}
public void foo_bar() {
// "a" is not in scope for foo_bar, so this won't compile
a = 20;
// ...
}
would definitely be invalid. I don't think that this was what you were driving at in your question though.
You can do something somewhat similar to what you ask for using closures but they're a bit tricky to work with. Basically, something like this would be valid (and I'm not sitting in front of an IDE so forgive me if the syntax is a little off):
Func<int> GetCounter() {
int count = 0;
// This will capture the count variable from its context
Func<int> method = () => ++count;
return method;
}
While a fair number of languages (including some versions of C++ now I guess) have closures (or some similar variant), there seems to be little consistency in exactly how they work across languages (e.g. on whether the "count" variable should be immutable once it's captured) so it's important to check the documentation for the language you're using (in this case, C#) to understand exactly how they work.
In terms of the first code sample I provide, I doubt that that's what you were asking about, but just as a brief digression you probably wouldn't really want it to be the allowable anyway (and again I suspect that this isn't the syntax/semantics you're asking about) as it would quickly lead to unexpected/undefined behavior. For example:
If you have a local variable a that's initialized in Foo() and you refer to it in Foo_Bar() before you run Foo(), what should its value be?
If you run Foo() to initialize the variable, edit the variable in Foo_Bar(), and then run Foo() again, should you re-initialize the variable or allow it to remain what Foo_Bar() set it to?
Is it safe to garbage collect a local variable after the method call completes, or might it be referred to again?
See the following:
public class SomeObject
{
public int SomeProperty { get; set; } = 6;
// ...
}
public class SomeOtherObject
{
// ..
}
void foo() {
// What is the content of "a" before foo() runs?
object a = new SomeObject();
// Which "a" should this refer to - the one in foo() or the one in foo_bar()?
// Also, is this a valid cast given that we haven't specified that SomeOtherObject can be cast to SomeObject?
var b = (SomeObject)a;
// If we run foo() again, should "b" retain the value of SetProperty or set it back to the initial value (6)?
b.SetProperty = 10;
// ...
// Is it safe to garbage collect "a" at this point (or will foo_bar refer to it)?
}
void foo_bar() {
object a = new SomeOtherObject();
// ...
}
As a very simplified and stupid example of what I'm dealing with, suppose I had the following class with a simple static int property:
public class MyClass
{
public static int MyVar { get; set; }
}
So, if I wanted to set that property via code, it would be easy enough with something such as:
MyClass.MyVar = 2;
But, how could I take care of (again, to simplify the example) passing in a string and have it converted to an int?
The only way I could think of doing it is to create a helper method such as:
public class MyClass
{
public static int MyVar { get; private set; }
public static void SetMyVar(string sMyVar)
{
MyVar = int.Parse(sMyVar);
}
}
And then in code run:
MyClass.SetMyVar("2");
I would love to know if there was a better way to accomplish this than having to add in that extra method.
Although you definitely shouldn't do this because it's confusing to read, you could create the property this way
class MyClass
{
private static int _property = 0;
public static object Property
{
get
{
return _property;
}
set
{
_property = Convert.ToInt32(value);
}
}
}
You would have to cast this to an int whenever you wanted to use it as an integer but this is best I could think of.
is this what you were trying to do?
class newclass
{
private static int MyVarValue = 0;
public static int MyVar
{
get;
set
{
MyVarValue = Convert.ToInt32(value);
}
}
}
This would not compile because the value that a property gets set to has to be of the same type as the property itself. But if you are taking a list of objects in a constructor and assigning them to the properties, there you can do something like this...
class newclass
{
private static int MyVarValue = 0;
public newclass(List<object> startingList)
{
MyVarValue = Convert.ToInt32(startingList[0]);
}
}
You can use the compiler's method overload resolution to pick a SetMyValue method depending on the type of the argument. Inside each SetMyValue method you have a mechanism to convert all of the different input values to the same underlying type.
Doing this is probably a bad idea - but here goes anyway. It doesn't have quite the semantics that you're asking for but it's close:
//A class with multiple 'set' methods that will silently handle
//type conversions
class MyClass{
private int myValue;
public int MyValue { { get return this.myValue; } }
public void SetMyValue(int value){
this.myValue = value;
}
public void SetMyValue(string value){
this.myValue = Convert.ToInt32(value);
}
}
In statically typed languages, switching types silently in a way that loses information is not a very wise idea. There are other, dynamically typed languages that let you play fast and loose with types but C# is not one of them. You have to go out of your way in C# to get dynamic typing.
Doing this is probably a pain in the butt from a maintenance standpoint. I would put some more thought into the underlying problem that you're trying to solve that lead to this question.
I want to be able to store code in a database and then execute it dynamically (using Roslyn). However, I want to be able to (inject?) properties from calling code. See below:
using Roslyn.Scripting.CSharp;
using RoslynMVCTest.Interfaces;
namespace RoslynMVCTest.Services
{
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public bool SomeMethod()
{
string codeString = #"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService {get;set;}
public static bool DoSomething()
{
return IInjectedService.SomeOtherMethod();
}
}";
var engine = new ScriptEngine();
var session = engine.CreateSession(_injectedService);
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>("SomethingDoer.DoSomething()");
return result;
}
}
}
I realize there are probably syntax and other issues here, but it's a good representation of what I want to do. Is there a way to do this?
First I'm going to answer your question matching your original code as closely as possible. Second, I'm going to show a far more concise example that might in fact be all that you're after.
You can certainly declare your type as you've done, but a few things will have to be fixed to even get it to make sense.
Your SomethingDoer class declares a non-static InjectedService property, despite the fact that you attempt to consume that property in a static method. I will assume for the sake of discussion that you intended SomethingDoer.DoSomething to be non-static as well and will thus instanatiate that class.
public static bool DoSomething()
To:
public bool DoSomething()
The "sesion" you pass to CreateSession is your actual service. To understand why this won't work, you have to understand what the argument you pass to CreateSession means and what's done with it. What the "session" means is that all the public properties of that object are available to your scripting session as raw identifiers without the need to . reference them on any target. Thus, to get your code working, I've introduced a new class (inner to the main service class for convenience) called Session:
public class Session
{
public IInjectedService InjectedService { get; set; }
}
Furthermore, I've used this new class when invoking CreateSession:
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
What this means is that the property InjectedService is now available to you within your codeString.
Perhaps most importantly, your code codeString is never actually consumed by your code! You seem to have, understandably, conceived of this process as setting up a string for your code, and then imagined that you could then invoke some arbitrary method within it. On the contrary, there is only one block of code. So if you really want to declare a whole class in your script-code, you're still going to have to consume it directly within your script-code as well. This means that the final two lines of your codeString should actually look like:
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
Here we're instantiating SomethingDoer (because of change 1.) and setting the service property by the implicit InjectedService value provided by the session (because of change 2.).
For completeness, here is the fully working sample code:
namespace RoslynMVCTest.Interfaces
{
public interface IInjectedService
{
bool SomeOtherMethod();
}
}
namespace RoslynMVCTest.Services
{
using RoslynMVCTest.Interfaces;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new MyService(new InjectedService()).SomeMethod());
Console.ReadLine();
}
}
class InjectedService : IInjectedService
{
public bool SomeOtherMethod()
{
return true;
}
}
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public class Session
{
public IInjectedService InjectedService { get; set; }
}
public bool SomeMethod()
{
string codeString = #"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService { get; set; }
public bool DoSomething()
{
return InjectedService.SomeOtherMethod();
}
}
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
var engine = new ScriptEngine();
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>(codeString);
return result;
}
}
}
Alternative Approach
If all you want to do is allow your script to run some code that interacts with your service, you can see how this is actually extremely trivial given all the points made above. Thus to concisely express what might be the intent of your original code, all you'd have to do is:
var result = session.Execute<bool>("InjectedService.SomeOtherMethod()");
The code passed in here is simply the body of the service method in the long-winded first example. Quite possibly this is all you need or want.
Is it possible to get value without creating an instance ?
I have this class:
public class MyClass
{
public string Name{ get{ return "David"; } }
public MyClass()
{
}
}
Now I need get the value "David", without creating instance of MyClass.
Real answer: no. It's an instance property, so you can only call it on an instance. You should either create an instance, or make the property static as shown in other answers.
See MSDN for more information about the difference between static and instance members.
Tongue-in-cheek but still correct answer:
Is it possible to get value without creating an instance ?
Yes, but only via some really horrible code which creates some IL passing in null as this (which you don't use in your property), using a DynamicMethod. Sample code:
// Jon Skeet explicitly disclaims any association with this horrible code.
// THIS CODE IS FOR FUN ONLY. USING IT WILL INCUR WAILING AND GNASHING OF TEETH.
using System;
using System.Reflection.Emit;
public class MyClass
{
public string Name { get{ return "David"; } }
}
class Test
{
static void Main()
{
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var dynamicMethod = new DynamicMethod("Ugly", typeof(string),
Type.EmptyTypes);
var generator = dynamicMethod.GetILGenerator();
generator.Emit(OpCodes.Ldnull);
generator.Emit(OpCodes.Call, method);
generator.Emit(OpCodes.Ret);
var ugly = (Func<string>) dynamicMethod.CreateDelegate(
typeof(Func<string>));
Console.WriteLine(ugly());
}
}
Please don't do this. Ever. It's ghastly. It should be trampled on, cut up into little bits, set on fire, then cut up again. Fun though, isn't it? ;)
This works because it's using call instead of callvirt. Normally the C# compiler would use a callvirt call even if it's not calling a virtual member because that gets null reference checking "for free" (as far as the IL stream is concerned). A non-virtual call like this doesn't check for nullity first, it just invokes the member. If you checked this within the property call, you'd find it's null.
EDIT: As noted by Chris Sinclair, you can do it more simply using an open delegate instance:
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var openDelegate = (Func<MyClass, string>) Delegate.CreateDelegate
(typeof(Func<MyClass, string>), method);
Console.WriteLine(openDelegate(null));
(But again, please don't!)
You can make that property static
public static string Name{ get{ return "David"; } }
Usage:
MyClass.Name;
You requirements do seem strange, but I think you're looking for some kind of metadata. You can use an attribute to achieve this:
public class NameAttribute : Attribute {
public string Name { get; private set; }
public NameAttribute(string name) {
Name = name;
}
}
[Name("George")]
public class Dad {
public string Name {
get {
return NameGetter.For(this.GetType());
}
}
}
[Name("Frank")]
public class Son : Dad {
}
public static class NameGetter {
public static string For<T>() {
return For(typeof(T));
}
public static string For(Type type) {
// add error checking ...
return ((NameAttribute)type.GetCustomAttributes(typeof(NameAttribute), false)[0]).Name;
}
}
Now this code can get names with and without instances:
Console.WriteLine(new Dad().Name);
Console.WriteLine(new Son().Name);
Console.WriteLine(NameGetter.For<Dad>());
Console.WriteLine(NameGetter.For<Son>());
You can make your property static, as pointed out by many others.
public static string Name{ get{ return "David"; } }
Be aware that this means your instances of MyClass will no longer have their own Name property, since static members belong to the class, not the individual object instances of it.
Edit:
In a note, you mentioned that you want to override the Name property in subclasses. At the same time, you want to be able to access it at the class level (access it without creating an instance of your class).
For the static properties, you would simply create a new Name property in each class. Since they are static, you're always (almost always, yay reflection) going to access them using a specific class, so you'd be specifying which version of Name you want to get. If you want to try and hack polymorphism in there and get the name from any given subclass of MyClass, you could do so using reflection, but I wouldn't recommend doing so.
Using the example from your comment:
public class Dad
{
public static string Name { get { return "George"; }
}
public class Son : Dad
{
public static string Name { get{ return "Frank"; }
}
public static void Test()
{
Console.WriteLine(Dad.Name); // prints "George"
Console.WriteLine(Son.Name); // prints "Frank"
Dad actuallyASon = new Son();
PropertyInfo nameProp = actuallyASon.GetType().GetProperty("Name");
Console.WriteLine(nameProp.GetValue(actuallyASon, null)); // prints "Frank"
}
As a side note, since you are declaring a property that has only a getter and it is returning a constant value, I recommend possibly using a const or static readonly variable instead.
public const string Name = "David";
public static readonly string Name = "David";
Usage for both would be the same:
string name = MyClass.Name;
The main benefit (and drawback) of const is that all references to it are actually replaced by its value when the code is compiled. That means it will be a little faster, but if you ever change its value, you will need to recompile ALL code that references it.
Whenever you write C# code, always check if your method and property getter/setter code does anything at all with other instance members of the class. If they don't, be sure to apply the static keyword. Certainly the case here, it trivially solves your problem.
The reason I really post to this question is that there's a bit of language bias at work in some of the answers. The C# rule that you can't call an instance method on a null object is a specific C# language rule. It is without a doubt a very wise one, it really helps to troubleshoot NullReferenceExceptions, they are raised at the call site instead of somewhere inside of a method where it gets very hard to diagnose that the this reference is null.
But this is certainly not a requirement to the CLR, nor of every language that run on the CLR. In fact, even C# doesn't enforce it consistently, you can readily bypass it in an extension method:
public static class Extensions {
public static bool IsNullOrEmpty(this string obj) {
return obj != null && obj.Length > 0;
}
}
...
string s = null;
bool empty = s.IsNullOrEmpty(); // Fine
And using your property from a language that doesn't have the same rule works fine as well. Like C++/CLI:
#include "stdafx.h"
using namespace System;
using namespace ClassLibrary1; // Add reference
int main(array<System::String ^> ^args)
{
MyClass^ obj = nullptr;
String^ name = obj->Name; // Fine
Console::WriteLine(name);
return 0;
}
Create a static property:
public class MyClass
{
public static string Name { get { return "David"; } }
public MyClass()
{
}
}
Get it like so:
string name1 = MyClass.Name;
That is not possible. As Name is an instance property, you can only get its value if you have an instance.
Also, note that you are not talking about a parameter, but about a property.
Create a static class or a static property, and you don't have to explicitly instantiate it.