An object method is required for non static, field method - c#

I've no experience of using C# but as part of one of our college modules we have to create a slot machine application. We created a Gambler class and I have to make a CheckBalance class where I will call the Token method from the Gambler class. But I get the error that is mentioned in the thread title.
Int tokens = Gambler.Tokens;
The above line is where I am getting my error.
This is my code:
enter code herenamespace CasinoClasslibrary
{
public class Gambler
{
public string Name { get; private set; }
public int Age { get; private set; }
public long CreditCardNum { get; private set; }
public int Tokens { get; public set; }
public string Username { get; private set; }
public string Password { private get; public set; }
public Gambler(string Name, int Age, long CreditCardNum, int Tokens, string Username, string Password)
{
this.Name = Name;
this.Age = Age;
this.CreditCardNum = CreditCardNum;
this.Tokens = Tokens;
this.Username = Username;
this.Password = Password;
}
}
public class Cashout : Gambler
{
public Boolean CheckBalance()
{
int tokens = Gambler.Tokens;
return true;
}
}
}

Since you are inheriting from Gambler I suspect that you need to access base.Tokens like:
public Boolean CheckBalance()
{
int tokens = base.Tokens; //here
return true;
}
Otherwise since Toakens is an instance member you have to create object of Gambler and then access it.
There are other errors in your code as well. You haven't defined a default (parameter less) constructor in your base class and you need to call the existing base constructor in your child class.
public class Cashout : Gambler
{
public Cashout()
: base("",0, 0, 1, "", "") //something like this
{
}
public Boolean CheckBalance()
{
int tokens = base.Tokens;
return true;
}
}

Because Cashout inherits from Gambler you can just do this. This is because the Cashout instance will have a Tokens property as well.
public class Cashout : Gambler
{
public Boolean CheckBalance()
{
int tokens = Tokens;
return true;
}
}
However, if you intended the method to be static, you will need an instance of Gambler to access that property and this should be passed into the static method as such.
public class Cashout : Gambler
{
public static Boolean CheckBalance(Gambler myGambler)
{
int tokens = myGambler.Tokens;
return true;
}
}
Finally, if you intended this Tokens property to be static itself, you need to declare it as such
public static int Tokens;
You may also want a static constructor to set it up.

Tokens is not static method but you try to access it through static construct (class level).
can make this work by declaring it static (although that's not likely what you want)
public static int Tokens { get; public set; }
or by instantiating Gambler
new Gambler().Tokens;

Related

How to get data from an Object from another Class?

Hey I have a problem with my code.
Sorry if the question is too easy but I can't find a solution.
I have an object called user in class 1
The Object User has this variables.
public class User
{
public string email { get; set; }
public string password { get; set; }
public string mobilenumber { get; set; }
public string service { get; set; }
public override string ToString()
{
return $"{email}: {password}: {mobilenumber}: {service}";
}
}
These variables are filled with data in class 1
Now I want to access these data in class 2 and display them to me.
I tried something like
Class Firstclass{
public void OnLogin(){
public User user = new User();
user.email = abc#abc.com
}
}
Class B{
protected override async Task OnInitializedAsync(){
Firstclass firstclass = new Firstclass();
string output = firstclass.user.email;
}
}
There are several ways to do that. A simple one would be to instantiate the User inside the constructor:
public Class Firstclass
{
User user;
public FirstClass()
{
this.user = new User();
this.user.email = "abc#abc.com";
// more data could be here or use a local method to fill user's fields
}
public User
{
get
{
return this.user;
}
set
{
this.user = value;
}
}
}
Try to avoid using a public field, rather use a public property like User in above. Then in Class B, you would have:
Class B
{
protected override async Task OnInitializedAsync()
{
Firstclass firstclass = new Firstclass();
string output = firstclass.User.email;
}
}

Implement different return types from an interface using generics

I have an interface defined like this:
public interface ISomeOrderService
{
T GetUserNameandPass<T>();
Task<IEnumerable<T>> FetchOrdersAsync<T>(bool useProxy, bool impersonateProxyUser);
}
For the GetUserNameandPass, I want it to return the following object in the implementing class:
public class NameandPass
{
public string UserName { get; set; }
public string Password { get; set; }
}
On the other hand, for the FetchOrdersAsync, I want it to return the following object in the implementing class:
public class SomeOrder
{
public string prop1 { get; set; }
public DateTime prop2 { get; set; }
internal static async Task<IEnumerable<SomeOrder>> ConvertServiceResponseToSomeOrderListAsync(SomeResponse someResponse)
{
//someResult
return someResult.ToList();
}
}
I have my implementing class that looks like this:
public class SomeOrderService : ISomeOrderService
{
private IAMSService _aMSService;
public SomeOrderService()
{
_aMSService = new AMSService();
}
public NameandPass GetUserNameandPass()
{
return _aMSService.GetProxyUser<NameandPass>("SomeTypeOfUser");
}
public async Task<IEnumerable<SomeOrder>> FetchOrdersAsync<SomeOrder>(bool useProxy, bool impersonateProxyUser)
{
//someResponse;
return await SomeOrder.ConvertServiceResponseToSomeOrderListAsync(someResponse);
}
}
Here I have this first error in line:
return await SomeOrder.ConvertServiceResponseToSomeOrderListAsync(someResponse);
SomeOrder is a type parameter, which is not valid in the given context.
And the other error comes in the AMSService:
public class AMSService : IAMSService
{
public NameandPass GetProxyUser<NameandPass>(string proxyUser)
{
//someProxyUserResultObject
return new NameandPass { UserName = someProxyUserResultObject.Username, Password = someProxyUserResultObject.Password };
}
}
Here I get this second error:
AMSService doesn't implement member 'IAMSService.GetProxyUser<T>(string)'. 'AMSService.GetProxyUser<NameandPass>(string)' cannot implement 'IAMSService.GetProxyUser<T>(string)' because it does not have matching return type of 'T'.'
The IAMSService.cs looks like this:
public interface IAMSService
{
T GetProxyUser<T>(string proxyUser);
}
What could I be doing wrong here? Is my Interface definition from the start not adequate?
Thank You for the help!

Avoid Casting in following Code by using Generics

I am new to generics and just wondering if it's possible to avoid the casting in the following code using better OO approach.
public class CollectorFactory
{
public static MyCollector Create(ICredential credential)
{
return new MyCollector(credential);
}
}
public class MyCollector {
public MyCredential Credential { get; set; }
public MyCollector(ICredential credential)
{
this.Credential = (MyCredential)credential;
}
public void Show()
{
Console.WriteLine(this.Credential.Username);
Console.WriteLine(this.Credential.AuthToken);
}
}
public class MyCredential : ICredential
{
public string Username{ get; set; }
public string AuthToken { get; set; }
}
public interface ICredential
{
}
Is there a way to save the casting of ICredential to MyCredential in MyCollector's Constructor? I don't have option to put Username and AuthToken in ICredential as it's implemented by two different Credentials that both have different set of properties. CollectorFactory will be returning different MyCollector instances in the future and both need to have different credentials.
Any help would be really appreciated.
I don't think it's possible given that you're implementing different credentials and trying to use them for ICredential as well.
Here is a way of doing this using generics. Please read my comments in the code.
public class CollectorFactory<T>
{
public T Create(ICredential credential)
{
return (T)Activator.CreateInstance(typeof(T), credential);
}
}
public class MyCollector : BaseCollector
{
public dynamic Credential { get; private set; }
public MyCollector(ICredential credential)
: base(credential)
{
this.Credential = credential;
}
// Having this method here limits your ability to make it more generic.
// Consider moving this to MyCredential since it refers to specific properties in MyCredential.
// If that is not what you want, then you must do a type check before calling methods/ accessing props in Credentials.
public void Show()
{
Console.WriteLine(this.Credential.Username);
Console.WriteLine(this.Credential.AuthToken);
}
}
public class MyCredential : ICredential
{
public string Username { get; set; }
public string AuthToken { get; set; }
}
public abstract class BaseCollector : ICredentialCollector
{
protected BaseCollector(ICredential credential)
{
if (credential == null)
{
throw new ArgumentNullException(nameof(credential));
}
}
}
public interface ICredentialCollector
{
}
public interface ICredential
{
}
// test implementation
public class TestClass
{
public void AuthFactoryTest()
{
// test auth instance
MyCredential auth = new MyCredential() {AuthToken = "asfgasdgdfg", Username = "xuser"};
// Create test factory
var fact = new CollectorFactory<MyCollector>();
var myCollector = fact.Create(auth);
// Do what you need to do to collector object
myCollector.Show();
}
}
Generics isn't the solution in this case. The issue here is that your factory is returning a specific type (MyCollector). A solution around this would be the following:
public class CollectorFactory
{
public static ICollector Create(MyCredential credential)
{
return new MyCollector(credential);
}
public static ICollector Create(OtherCredential credential)
{
return new OtherCollector(credential);
}
}
public interface ICollector
{
void Show();
}
public class MyCollector : ICollector
{
public MyCredential Credential { get; set; }
public MyCollector(MyCredential credential)
{
this.Credential = credential;
}
public void Show()
{
Console.WriteLine(this.Credential.Username);
Console.WriteLine(this.Credential.AuthToken);
}
}
public class MyCredential : ICredential
{
public string Username{ get; set; }
public string AuthToken { get; set; }
}
public interface ICredential
{
}
The above is pretty much the canonical example of the Factory design pattern.
Instead of overloads you could also do typechecking in the factory:
public class CollectorFactory
{
public static ICollector Create(ICredential credential)
{
if(credential.GetType() == typeof(MyCredential))
return new MyCollector((MyCredential) credential);
if(credential.GetType() == typeof(OtherCredential ))
return new OtherCollector((OtherCredential ) credential);
}
}

inheriting a class with parameteraized constractor to reuse base properties

i'm trying to minimize use of constractors in derived classes, and have a base class to hold common properties
so i tried as follows
public class sharedData
{
public string GlobMeta;
public int GlobValue;
public sharedData(string meta, int value)
{
GlobMeta = meta;
GlobValue= value;
}
}
public class derivedData: sharedData
{
public string test;
test = string.Format("Shared meta = {0}, Shared Value = {1}",GlobMeta, GlobValue);
}
then use
var shared = new sharedData("desc", 1);
var derived = new derivedData();
var testData = derived.test;
so when i will create instance of derived it will use base (shared) values
wich is common to all derived classes.
how can i implement this, as my idea was to use less memory with large collections of data. and also clean code and ease of use.
You have declared a based class, sharedData, without parameterless constructor. Therefore, any class that inherit that class must define a base constructor. You can't rely on the the compiler do job the job for you anymore.
public class derivedData : sharedData
{
public string test;
public derivedData(string meta, int value) : base(meta, value)
{
// you can't do assignment in the class scope, unless it can be done statically, it has to be inside a method block
test = string.Format("Shared meta = {0}, Shared Value = {1}", GlobMeta, GlobValue);
}
// or, if you prefer to have a parameterless ctor
public derivedData() : base("a default value for meta", default(int))
{
test = string.Format("Shared meta = {0}, Shared Value = {1}", GlobMeta, GlobValue);
}
}
EDIT: It seems that you are using this for global settings, in that case, you need to mark GlobMeta and GlobValue as static. Otherwise they won't be "shared" at all between different instance of sharedData/derivedData.
You should consider rewriting it as this :
public static class SharedData
{
public static string Meta { get; private set; }
public static int Value { get; private set; }
public static void SetData(string meta, int value)
{
Meta = meta;
Value = value;
}
}
public class DerivedData
{
public string Test
{
get { return string.Format("Shared meta = {0}, Shared Value = {1}", SharedData.Meta, SharedData.Value); }
}
}
EDIT 2 : If you need to have various instances of these, use the following :
public class SharedData
{
public string Meta { get; set; }
public int Value { get; set; }
public SharedData(string meta, int value)
{
Meta = meta;
Value = value;
}
}
public class DerivedData : SharedData
{
public string Test
{
get { return string.Format("Shared meta = {0}, Shared Value = {1}", Meta, Value); }
}
public DerivedData(string meta, int value) : base(meta, value)
{
}
// note: this is a copy ctor, changing data after this has been created, will not affect this.
public DerivedData(SharedData data) : base(data.Meta, data.Value)
{
}
}
I was thinking along the same lines as Xiaoy312, and wrote this while he was posting his second example:
public class SharedData
{
internal static string GlobMeta;
internal static int GlobValue;
public SharedData(string meta, int value)
{
GlobMeta = meta;
GlobValue = value;
}
public SharedData(){}
}
public class DerivedData: SharedData
{
public DerivedData() : base()
{
Console.WriteLine("Shared meta = {0}, Shared Value = {1}", GlobMeta, GlobValue);
}
}
Declaring the static variables as 'internal means they will only be accessible in the scope of 'SharedData and any classes derived from it.

Help with Singleton - Setting Auto Properties?

I'm trying to set my Auto Properties but they are non-static and so I get the error "Cannot access non-static property in static context" when trying to set the properties Credentials, Certificate, and UrlEndPoint.
public class PayPalProfile
{
#region Fields
static PayPalProfile _instance;
#endregion
#region Constructors
PayPalProfile()
{
// is only called if a new instance is created
SetProfileState();
}
#endregion
#region Properties
public static PayPalProfile CurrentProfile
{
get
{
if (_instance == null)
_instance = new PayPalProfile();
return _instance;
}
}
public CustomSecurityHeaderType Credentials { get; private set; }
public X509Certificate2 Certificate { get; private set; }
public string UrlEndPoint { get; private set;}
#endregion
#region Methods
private static void SetProfileState()
{
// Set the profile state
SetApiCredentials();
SetPayPalX509Certificate();
}
private static void SetApiCredentials()
{
Credentials = new CustomSecurityHeaderType
{
Credentials =
{
Username = PayPalConfig.CurrentConfiguration.ApiUserName,
Password = PayPalConfig.CurrentConfiguration.ApiPassword
}
};
UrlEndPoint = PayPalConfig.CurrentConfiguration.ExpressCheckoutSoapApiEndPoint;
}
private static void SetPayPalX509Certificate()
{
PayPalCerfiticate paypalCertificate = new PayPalCerfiticate();
Certificate = paypalCertificate.PayPalX509Certificate;
}
#endregion
}
There is no need for SetProfileState, SetApiCredentials and SetPayPalX509Certificate to be static.
SetApiCredentials and SetPayPalX509Certificate are setting values for non static properties and so an instance is required. By removing the static modifiers from the above mentioned methods the properties will be set on the instance being constructed when SetProfileState is called.
This means that you have a static method where you are trying to assign instance properties. As there is no instance available in static methods/properties, the error is given.
The example:
public class Test {
public int InstanceProperty { get; set; }
public static void StaticMethod() {
InstanceProperty = 55; // ERROR HERE
}
}
Instead bothe should either be in static or instance context:
public class Test {
public static int StaticProperty { get; set; }
public static void StaticMethod() {
StaticProperty = 55; // Ok
}
}
public class Test {
public int InstanceProperty { get; set; }
public void InstanceMethod() {
InstanceProperty = 55; // Ok
}
}

Categories